diff --git a/audits/099_unlistMarkets_certik_20240409.pdf b/audits/099_unlistMarkets_certik_20240409.pdf new file mode 100644 index 000000000..bf4c371c6 Binary files /dev/null and b/audits/099_unlistMarkets_certik_20240409.pdf differ diff --git a/audits/102_unlistMarkets_fairyproof_20240328.pdf b/audits/102_unlistMarkets_fairyproof_20240328.pdf new file mode 100644 index 000000000..c3a318187 Binary files /dev/null and b/audits/102_unlistMarkets_fairyproof_20240328.pdf differ diff --git a/contracts/Comptroller/ComptrollerStorage.sol b/contracts/Comptroller/ComptrollerStorage.sol index 52af5ccac..9ea99f83b 100644 --- a/contracts/Comptroller/ComptrollerStorage.sol +++ b/contracts/Comptroller/ComptrollerStorage.sol @@ -182,7 +182,7 @@ contract ComptrollerV3Storage is ComptrollerV2Storage { /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market. address public borrowCapGuardian; - /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which corresponds to unlimited borrowing. + /// @notice Borrow caps enforced by borrowAllowed for each vToken address. mapping(address => uint256) public borrowCaps; } diff --git a/contracts/Comptroller/Diamond/facets/MarketFacet.sol b/contracts/Comptroller/Diamond/facets/MarketFacet.sol index e1c9b3731..12e4ca787 100644 --- a/contracts/Comptroller/Diamond/facets/MarketFacet.sol +++ b/contracts/Comptroller/Diamond/facets/MarketFacet.sol @@ -22,6 +22,9 @@ contract MarketFacet is IMarketFacet, FacetBase { /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account event DelegateUpdated(address indexed approver, address indexed delegate, bool approved); + /// @notice Emitted when an admin unlists a market + event MarketUnlisted(address indexed vToken); + /// @notice Indicator that this is a Comptroller contract (for inspection) function isComptroller() public pure returns (bool) { return true; @@ -33,7 +36,25 @@ contract MarketFacet is IMarketFacet, FacetBase { * @return A dynamic list with the assets the account has entered */ function getAssetsIn(address account) external view returns (VToken[] memory) { - return accountAssets[account]; + uint256 len; + VToken[] memory _accountAssets = accountAssets[account]; + uint256 _accountAssetsLength = _accountAssets.length; + + VToken[] memory assetsIn = new VToken[](_accountAssetsLength); + + for (uint256 i; i < _accountAssetsLength; ++i) { + Market memory market = markets[address(_accountAssets[i])]; + if (market.isListed) { + assetsIn[len] = _accountAssets[i]; + ++len; + } + } + + assembly { + mstore(assetsIn, len) + } + + return assetsIn; } /** @@ -112,6 +133,42 @@ contract MarketFacet is IMarketFacet, FacetBase { return results; } + /** + * @notice Unlist a market by setting isListed to false + * @dev Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0 + * @param market The address of the market (vToken) to unlist + * @return uint256 0=success, otherwise a failure. (See enum Error for details) + */ + function unlistMarket(address market) external returns (uint256) { + ensureAllowed("unlistMarket(address)"); + + Market storage _market = markets[market]; + + if (!_market.isListed) { + return fail(Error.MARKET_NOT_LISTED, FailureInfo.UNLIST_MARKET_NOT_LISTED); + } + + require(actionPaused(market, Action.BORROW), "borrow action is not paused"); + require(actionPaused(market, Action.MINT), "mint action is not paused"); + require(actionPaused(market, Action.REDEEM), "redeem action is not paused"); + require(actionPaused(market, Action.REPAY), "repay action is not paused"); + require(actionPaused(market, Action.ENTER_MARKET), "enter market action is not paused"); + require(actionPaused(market, Action.LIQUIDATE), "liquidate action is not paused"); + require(actionPaused(market, Action.SEIZE), "seize action is not paused"); + require(actionPaused(market, Action.TRANSFER), "transfer action is not paused"); + require(actionPaused(market, Action.EXIT_MARKET), "exit market action is not paused"); + + require(borrowCaps[market] == 0, "borrow cap is not 0"); + require(supplyCaps[market] == 0, "supply cap is not 0"); + + require(_market.collateralFactorMantissa == 0, "collateral factor is not 0"); + + _market.isListed = false; + emit MarketUnlisted(market); + + return uint256(Error.NO_ERROR); + } + /** * @notice Removes asset from sender's account liquidity calculation * @dev Sender must not have an outstanding borrow balance in the asset, diff --git a/contracts/Comptroller/Diamond/facets/PolicyFacet.sol b/contracts/Comptroller/Diamond/facets/PolicyFacet.sol index 9702f653e..ff16ff1a1 100644 --- a/contracts/Comptroller/Diamond/facets/PolicyFacet.sol +++ b/contracts/Comptroller/Diamond/facets/PolicyFacet.sol @@ -110,9 +110,11 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { // Pausing is a very serious situation - we revert to sound the alarms checkProtocolPauseState(); checkActionPauseState(vToken, Action.BORROW); - ensureListed(markets[vToken]); + uint256 borrowCap = borrowCaps[vToken]; + require(borrowCap != 0, "market borrow cap is 0"); + if (!markets[vToken].accountMembership[borrower]) { // only vTokens may call borrowAllowed if borrower not in market require(msg.sender == vToken, "sender must be vToken"); @@ -128,12 +130,8 @@ contract PolicyFacet is IPolicyFacet, XVSRewardsHelper { return uint256(Error.PRICE_ERROR); } - uint256 borrowCap = borrowCaps[vToken]; - // Borrow cap of 0 corresponds to unlimited borrowing - if (borrowCap != 0) { - uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount); - require(nextTotalBorrows < borrowCap, "market borrow cap reached"); - } + uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount); + require(nextTotalBorrows <= borrowCap, "market borrow cap reached"); (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal( borrower, diff --git a/contracts/Comptroller/Diamond/facets/SetterFacet.sol b/contracts/Comptroller/Diamond/facets/SetterFacet.sol index d33ac2ef6..7c82a7fea 100644 --- a/contracts/Comptroller/Diamond/facets/SetterFacet.sol +++ b/contracts/Comptroller/Diamond/facets/SetterFacet.sol @@ -299,9 +299,9 @@ contract SetterFacet is ISetterFacet, FacetBase { /** * @notice Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert - * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to unlimited borrowing + * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed * @param vTokens The addresses of the markets (tokens) to change the borrow caps for - * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing + * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed */ function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external { ensureAllowed("_setMarketBorrowCaps(address[],uint256[])"); diff --git a/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol b/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol index 684d76f21..5a5496896 100644 --- a/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol +++ b/contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol @@ -31,4 +31,6 @@ interface IMarketFacet { function getAllMarkets() external view returns (VToken[] memory); function updateDelegate(address delegate, bool allowBorrows) external; + + function unlistMarket(address market) external returns (uint256); } diff --git a/contracts/Utils/ErrorReporter.sol b/contracts/Utils/ErrorReporter.sol index 29238b9e4..327e57922 100644 --- a/contracts/Utils/ErrorReporter.sol +++ b/contracts/Utils/ErrorReporter.sol @@ -48,7 +48,8 @@ contract ComptrollerErrorReporter { SET_VAI_MINT_RATE_CHECK, SET_VAICONTROLLER_OWNER_CHECK, SET_MINTED_VAI_REJECTION, - SET_TREASURY_OWNER_CHECK + SET_TREASURY_OWNER_CHECK, + UNLIST_MARKET_NOT_LISTED } /** diff --git a/deploy/010-facet-upgrade.ts b/deploy/010-facet-upgrade.ts new file mode 100644 index 000000000..f5e983f2d --- /dev/null +++ b/deploy/010-facet-upgrade.ts @@ -0,0 +1,34 @@ +import { DeployFunction } from "hardhat-deploy/types"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const { deployments, getNamedAccounts } = hre; + const { deploy } = deployments; + + const { deployer } = await getNamedAccounts(); + + await deploy("PolicyFacet", { + from: deployer, + args: [], + log: true, + autoMine: true, + }); + + await deploy("SetterFacet", { + from: deployer, + args: [], + log: true, + autoMine: true, + }); + + await deploy("MarketFacet", { + from: deployer, + args: [], + log: true, + autoMine: true, + }); +}; + +func.tags = ["FacetUpgrade"]; + +export default func; diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index 07559e620..61d1ec95c 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -13064,7 +13064,7 @@ ] }, "MarketFacet": { - "address": "0x9622522d94BdEe9b1d7C2CD944e3ed74B33BD9Cf", + "address": "0x4b093a3299F39615bA6b34B7897FDedCe7b83D63", "abi": [ { "anonymous": false, @@ -13180,6 +13180,19 @@ "name": "MarketListed", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketUnlisted", + "type": "event" + }, { "constant": false, "inputs": [ @@ -13957,6 +13970,27 @@ "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "unlistMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ @@ -17306,7 +17340,7 @@ ] }, "PolicyFacet": { - "address": "0x95CC56f266BC95Ae2486cb0cFeda1054B4aA4086", + "address": "0x93e7Ff7c87B496aE76fFb22d437c9d46461A9B51", "abi": [ { "anonymous": false, @@ -26413,7 +26447,7 @@ ] }, "SetterFacet": { - "address": "0x7dc9E7b21a9E343f4AD926b8B00Cff5adf5c1CdE", + "address": "0x9B0D9D7c50d90f23449c4BbCAA671Ce7cd19DbCf", "abi": [ { "anonymous": false, diff --git a/deployments/bscmainnet/MarketFacet.json b/deployments/bscmainnet/MarketFacet.json index 5eee14a34..655cc7fb3 100644 --- a/deployments/bscmainnet/MarketFacet.json +++ b/deployments/bscmainnet/MarketFacet.json @@ -1,5 +1,5 @@ { - "address": "0x9622522d94BdEe9b1d7C2CD944e3ed74B33BD9Cf", + "address": "0x4b093a3299F39615bA6b34B7897FDedCe7b83D63", "abi": [ { "anonymous": false, @@ -115,6 +115,19 @@ "name": "MarketListed", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketUnlisted", + "type": "event" + }, { "constant": false, "inputs": [ @@ -892,6 +905,27 @@ "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "unlistMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ @@ -1155,28 +1189,28 @@ "type": "function" } ], - "transactionHash": "0x659498e5a6280ca4d55a9587f8d8d453fe3c8ea54a17c27561180e2dfa39c43c", + "transactionHash": "0x580b94004f9728bcea4f2748704eca243c160cd2625e8d77464686671111bf31", "receipt": { "to": null, - "from": "0x7Bf1Fe2C42E79dbA813Bf5026B7720935a55ec5f", - "contractAddress": "0x9622522d94BdEe9b1d7C2CD944e3ed74B33BD9Cf", - "transactionIndex": 990, - "gasUsed": "1665799", + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x4b093a3299F39615bA6b34B7897FDedCe7b83D63", + "transactionIndex": 133, + "gasUsed": "2025920", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x0b4029b576af96abdbbe4e98304d076a29cbf0b971e216f3af7756290c92fd9a", - "transactionHash": "0x659498e5a6280ca4d55a9587f8d8d453fe3c8ea54a17c27561180e2dfa39c43c", + "blockHash": "0xe00bc3aed64b10a082d9572501dea30fbb916430f78b1fb6fe31e0038232a809", + "transactionHash": "0x580b94004f9728bcea4f2748704eca243c160cd2625e8d77464686671111bf31", "logs": [], - "blockNumber": 36961174, - "cumulativeGasUsed": "98074870", + "blockNumber": 39374395, + "cumulativeGasUsed": "14175746", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "ad834ffdd224ebe1944f429cc9972360", - "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"DelegateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketExited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketListed\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"_supportMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"checkMembership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"vTokens\",\"type\":\"address[]\"}],\"name\":\"enterMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenAddress\",\"type\":\"address\"}],\"name\":\"exitMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAllMarkets\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAssetsIn\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isComptroller\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateCalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateVAICalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"updateDelegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the methods related to the market's management in the pool\",\"methods\":{\"_supportMarket(address)\":{\"details\":\"Allows a privileged role to add and list markets to the Comptroller\",\"params\":{\"vToken\":\"The address of the market (token) to list\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"checkMembership(address,address)\":{\"params\":{\"account\":\"The address of the account to check\",\"vToken\":\"The vToken to check\"},\"return\":\"True if the account is in the asset, otherwise false\"},\"enterMarkets(address[])\":{\"params\":{\"vTokens\":\"The list of addresses of the vToken markets to be enabled\"},\"return\":\"Success indicator for whether each corresponding market was entered\"},\"exitMarket(address)\":{\"details\":\"Sender must not have an outstanding borrow balance in the asset, or be providing necessary collateral for an outstanding borrow\",\"params\":{\"vTokenAddress\":\"The address of the asset to be removed\"},\"return\":\"Whether or not the account successfully exited the market\"},\"getAllMarkets()\":{\"details\":\"The automatic getter may be used to access an individual market\",\"return\":\"The list of market addresses\"},\"getAssetsIn(address)\":{\"params\":{\"account\":\"The address of the account to pull assets for\"},\"return\":\"A dynamic list with the assets the account has entered\"},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"details\":\"Used in liquidation (called in vToken.liquidateBorrowFresh)\",\"params\":{\"actualRepayAmount\":\"The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\",\"vTokenBorrowed\":\"The address of the borrowed vToken\",\"vTokenCollateral\":\"The address of the collateral vToken\"},\"return\":\"(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\"},\"liquidateVAICalculateSeizeTokens(address,uint256)\":{\"details\":\"Used in liquidation (called in vToken.liquidateBorrowFresh)\",\"params\":{\"actualRepayAmount\":\"The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\",\"vTokenCollateral\":\"The address of the collateral vToken\"},\"return\":\"(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\"},\"updateDelegate(address,bool)\":{\"params\":{\"approved\":\"Whether to grant (true) or revoke (false) the borrowing or redeeming rights\",\"delegate\":\"The address to update the rights for\"}}},\"title\":\"MarketFacet\"},\"userdoc\":{\"methods\":{\"_supportMarket(address)\":{\"notice\":\"Add the market to the markets mapping and set it as listed\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"checkMembership(address,address)\":{\"notice\":\"Returns whether the given account is entered in the given asset\"},\"enterMarkets(address[])\":{\"notice\":\"Add assets to be included in account liquidity calculation\"},\"exitMarket(address)\":{\"notice\":\"Removes asset from sender's account liquidity calculation\"},\"getAllMarkets()\":{\"notice\":\"Return all of the markets\"},\"getAssetsIn(address)\":{\"notice\":\"Returns the assets an account has entered\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"isComptroller()\":{\"notice\":\"Indicator that this is a Comptroller contract (for inspection)\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"liquidateVAICalculateSeizeTokens(address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"updateDelegate(address,bool)\":{\"notice\":\"Grants or revokes the borrowing or redeeming delegate rights to / from an account If allowed, the delegate will be able to borrow funds on behalf of the sender Upon a delegated borrow, the delegate will receive the funds, and the borrower will see the debt on their account Upon a delegated redeem, the delegate will receive the redeemed amount and the approver will see a deduction in his vToken balance\"}},\"notice\":\"This facet contract contains functions regarding markets\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/MarketFacet.sol\":\"MarketFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which corresponds to unlimited borrowing.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x13aa5a019c0ea5149d00480b5a3e1281ec316f8d159c52705f45b4c75a5abcb8\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/MarketFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { IMarketFacet } from \\\"../interfaces/IMarketFacet.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\n/**\\n * @title MarketFacet\\n * @author Venus\\n * @dev This facet contains all the methods related to the market's management in the pool\\n * @notice This facet contract contains functions regarding markets\\n */\\ncontract MarketFacet is IMarketFacet, FacetBase {\\n /// @notice Emitted when an admin supports a market\\n event MarketListed(VToken indexed vToken);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account\\n event DelegateUpdated(address indexed approver, address indexed delegate, bool approved);\\n\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n function isComptroller() public pure returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Returns the assets an account has entered\\n * @param account The address of the account to pull assets for\\n * @return A dynamic list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n return accountAssets[account];\\n }\\n\\n /**\\n * @notice Return all of the markets\\n * @dev The automatic getter may be used to access an individual market\\n * @return The list of market addresses\\n */\\n function getAllMarkets() external view returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n * @param vTokenBorrowed The address of the borrowed vToken\\n * @param vTokenCollateral The address of the collateral vToken\\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256) {\\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateCalculateSeizeTokens(\\n address(this),\\n vTokenBorrowed,\\n vTokenCollateral,\\n actualRepayAmount\\n );\\n return (err, seizeTokens);\\n }\\n\\n /**\\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n * @param vTokenCollateral The address of the collateral vToken\\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\\n */\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256) {\\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateVAICalculateSeizeTokens(\\n address(this),\\n vTokenCollateral,\\n actualRepayAmount\\n );\\n return (err, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in the given asset\\n * @param account The address of the account to check\\n * @param vToken The vToken to check\\n * @return True if the account is in the asset, otherwise false\\n */\\n function checkMembership(address account, VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].accountMembership[account];\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return Success indicator for whether each corresponding market was entered\\n */\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n results[i] = uint256(addToMarketInternal(VToken(vTokens[i]), msg.sender));\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation\\n * @dev Sender must not have an outstanding borrow balance in the asset,\\n * or be providing necessary collateral for an outstanding borrow\\n * @param vTokenAddress The address of the asset to be removed\\n * @return Whether or not the account successfully exited the market\\n */\\n function exitMarket(address vTokenAddress) external returns (uint256) {\\n checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 oErr, uint256 tokensHeld, uint256 amountOwed, ) = vToken.getAccountSnapshot(msg.sender);\\n require(oErr == 0, \\\"getAccountSnapshot failed\\\"); // semi-opaque error code\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED);\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n uint256 allowed = redeemAllowedInternal(vTokenAddress, msg.sender, tokensHeld);\\n if (allowed != 0) {\\n return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed);\\n }\\n\\n Market storage marketToExit = markets[address(vToken)];\\n\\n /* Return true if the sender is not already \\u2018in\\u2019 the market */\\n if (!marketToExit.accountMembership[msg.sender]) {\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /* Set vToken account membership to false */\\n delete marketToExit.accountMembership[msg.sender];\\n\\n /* Delete vToken from the account\\u2019s list of assets */\\n // In order to delete vToken, copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n uint256 i;\\n for (; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n userAssetList[i] = userAssetList[len - 1];\\n userAssetList.length--;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(i < len);\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Allows a privileged role to add and list markets to the Comptroller\\n * @param vToken The address of the market (token) to list\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function _supportMarket(VToken vToken) external returns (uint256) {\\n ensureAllowed(\\\"_supportMarket(address)\\\");\\n\\n if (markets[address(vToken)].isListed) {\\n return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS);\\n }\\n\\n vToken.isVToken(); // Sanity check to make sure its really a VToken\\n\\n // Note that isVenus is not in active use anymore\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.isVenus = false;\\n newMarket.collateralFactorMantissa = 0;\\n\\n _addMarketInternal(vToken);\\n _initializeMarket(address(vToken));\\n\\n emit MarketListed(vToken);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account\\n * If allowed, the delegate will be able to borrow funds on behalf of the sender\\n * Upon a delegated borrow, the delegate will receive the funds, and the borrower\\n * will see the debt on their account\\n * Upon a delegated redeem, the delegate will receive the redeemed amount and the approver\\n * will see a deduction in his vToken balance\\n * @param delegate The address to update the rights for\\n * @param approved Whether to grant (true) or revoke (false) the borrowing or redeeming rights\\n */\\n function updateDelegate(address delegate, bool approved) external {\\n ensureNonzeroAddress(delegate);\\n require(approvedDelegates[msg.sender][delegate] != approved, \\\"Delegation status unchanged\\\");\\n\\n _updateDelegate(msg.sender, delegate, approved);\\n }\\n\\n function _updateDelegate(address approver, address delegate, bool approved) internal {\\n approvedDelegates[approver][delegate] = approved;\\n emit DelegateUpdated(approver, delegate, approved);\\n }\\n\\n function _addMarketInternal(VToken vToken) internal {\\n uint256 allMarketsLength = allMarkets.length;\\n for (uint256 i; i < allMarketsLength; ++i) {\\n require(allMarkets[i] != vToken, \\\"already added\\\");\\n }\\n allMarkets.push(vToken);\\n }\\n\\n function _initializeMarket(address vToken) internal {\\n uint32 blockNumber = getBlockNumberAsUint32();\\n\\n VenusMarketState storage supplyState = venusSupplyState[vToken];\\n VenusMarketState storage borrowState = venusBorrowState[vToken];\\n\\n /*\\n * Update market state indices\\n */\\n if (supplyState.index == 0) {\\n // Initialize supply state index with default value\\n supplyState.index = venusInitialIndex;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = venusInitialIndex;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n }\\n}\\n\",\"keccak256\":\"0x22b5fdac3e46d3e39472dc7186119d89df9af7b1b0a7b9186f66eae217c07170\"},\"contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface IMarketFacet {\\n function isComptroller() external pure returns (bool);\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256);\\n\\n function checkMembership(address account, VToken vToken) external view returns (bool);\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n function _supportMarket(VToken vToken) external returns (uint256);\\n\\n function getAssetsIn(address account) external view returns (VToken[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function updateDelegate(address delegate, bool allowBorrows) external;\\n}\\n\",\"keccak256\":\"0x95adef906110bb671f5945799498419905290a267e4da26ac838bfbfbd44dd57\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function getVAIAddress() public view returns (address);\\n\\n function getMintableVAI(address minter) public view returns (uint, uint);\\n\\n function mintVAI(address minter, uint mintVAIAmount) external returns (uint);\\n\\n function repayVAI(address repayer, uint repayVAIAmount) external returns (uint);\\n\\n function liquidateVAI(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint, uint);\\n\\n function _initializeVenusVAIState(uint blockNumber) external returns (uint);\\n\\n function updateVenusVAIMintIndex() external returns (uint);\\n\\n function calcDistributeVAIMinterVenus(address vaiMinter) external returns (uint, uint, uint, uint);\\n\\n function getVAIRepayAmount(address account) public view returns (uint);\\n}\\n\",\"keccak256\":\"0x17eb6edb1262c4effcad86f614ff20d00256278485054b11aa5cf011ff6f8a86\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0xc77c4dd91f93f778c5048fa0e68cc0cad2fd4a308add54f0172c507858ce06c8\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611d2a806100206000396000f3fe608060405234801561001057600080fd5b50600436106103415760003560e01c80639bb27d62116101b8578063c5b4db5511610104578063e37d4b79116100a2578063ede4edd01161007c578063ede4edd014610929578063f445d7031461094f578063f851a4401461097d578063fa6331d81461098557610341565b8063e37d4b79146108cc578063e85a2960146108f2578063e87554461461092157610341565b8063d3270f99116100de578063d3270f9914610860578063dce1544914610868578063dcfbc0c714610894578063ddbf54fd1461089c57610341565b8063c5b4db551461082c578063c5f956af14610850578063c7ee005e1461085857610341565b8063b8324c7c11610171578063bec04f721161014b578063bec04f7214610776578063bf32442d1461077e578063c299823814610786578063c488847b146107f657610341565b8063b8324c7c146106fa578063bb82aa5e14610748578063bbb8864a1461075057610341565b80639bb27d6214610601578063a76b3fda14610609578063a78dc7751461062f578063abfceffc14610674578063b0772d0b146106ea578063b2eafc39146106f257610341565b80634a584432116102925780637dc0d1d0116102305780638e8f294b1161020a5780638e8f294b1461057b5780639254f5e5146105c3578063929fe9a1146105cb57806394b2294b146105f957610341565b80637dc0d1d0146105275780638a7dc1651461052f5780638c1ac18a1461055557610341565b80635dd3fc9d1161026c5780635dd3fc9d146104e9578063719f701b1461050f57806376551383146105175780637d172bd51461051f57610341565b80634a5844321461049e5780634ada90af146104c457806352d84d1e146104cc57610341565b806321af4569116102ff5780632bc7e29e116102d95780632bc7e29e1461043a5780634088c73e1461046057806341a18d2c14610468578063425fad581461049657610341565b806321af45691461040657806324a3d6221461042a578063267822471461043257610341565b80627e3dd21461034657806302c3bcbb1461036257806304ef9d581461039a57806308e0225c146103a25780630db4b4e5146103d057806310b98338146103d8575b600080fd5b61034e61098d565b604080519115158252519081900360200190f35b6103886004803603602081101561037857600080fd5b50356001600160a01b0316610993565b60408051918252519081900360200190f35b6103886109a5565b610388600480360360408110156103b857600080fd5b506001600160a01b03813581169160200135166109ab565b6103886109c8565b61034e600480360360408110156103ee57600080fd5b506001600160a01b03813581169160200135166109ce565b61040e6109ee565b604080516001600160a01b039092168252519081900360200190f35b61040e6109fd565b61040e610a0c565b6103886004803603602081101561045057600080fd5b50356001600160a01b0316610a1b565b61034e610a2d565b6103886004803603604081101561047e57600080fd5b506001600160a01b0381358116916020013516610a36565b61034e610a53565b610388600480360360208110156104b457600080fd5b50356001600160a01b0316610a62565b610388610a74565b61040e600480360360208110156104e257600080fd5b5035610a7a565b610388600480360360208110156104ff57600080fd5b50356001600160a01b0316610aa1565b610388610ab3565b61034e610ab9565b61040e610ac7565b61040e610ad6565b6103886004803603602081101561054557600080fd5b50356001600160a01b0316610ae5565b61034e6004803603602081101561056b57600080fd5b50356001600160a01b0316610af7565b6105a16004803603602081101561059157600080fd5b50356001600160a01b0316610b0c565b6040805193151584526020840192909252151582820152519081900360600190f35b61040e610b32565b61034e600480360360408110156105e157600080fd5b506001600160a01b0381358116916020013516610b41565b610388610b75565b61040e610b7b565b6103886004803603602081101561061f57600080fd5b50356001600160a01b0316610b8a565b61065b6004803603604081101561064557600080fd5b506001600160a01b038135169060200135610cec565b6040805192835260208301919091528051918290030190f35b61069a6004803603602081101561068a57600080fd5b50356001600160a01b0316610d8b565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106d65781810151838201526020016106be565b505050509050019250505060405180910390f35b61069a610e01565b61040e610e63565b6107206004803603602081101561071057600080fd5b50356001600160a01b0316610e72565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61040e610e9c565b6103886004803603602081101561076657600080fd5b50356001600160a01b0316610eab565b610388610ebd565b61040e610ec3565b61069a6004803603602081101561079c57600080fd5b8101906020810181356401000000008111156107b757600080fd5b8201836020820111156107c957600080fd5b803590602001918460208302840111640100000000831117156107eb57600080fd5b509092509050610ed2565b61065b6004803603606081101561080c57600080fd5b506001600160a01b03813581169160208101359091169060400135610f68565b610834611010565b604080516001600160e01b039092168252519081900360200190f35b61040e611023565b61040e611032565b61040e611041565b61040e6004803603604081101561087e57600080fd5b506001600160a01b038135169060200135611050565b61040e611085565b6108ca600480360360408110156108b257600080fd5b506001600160a01b0381351690602001351515611094565b005b610720600480360360208110156108e257600080fd5b50356001600160a01b031661112b565b61034e6004803603604081101561090857600080fd5b5080356001600160a01b0316906020013560ff16611155565b610388611195565b6103886004803603602081101561093f57600080fd5b50356001600160a01b031661119b565b61034e6004803603604081101561096557600080fd5b506001600160a01b0381358116916020013516611445565b61040e611465565b610388611474565b60015b90565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b600d8181548110610a8757fe5b6000918252602090912001546001600160a01b0316905081565b602b6020526000908152604090205481565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff165b92915050565b60075481565b6025546001600160a01b031681565b6000610bca6040518060400160405280601781526020017f5f737570706f72744d61726b657428616464726573732900000000000000000081525061147a565b6001600160a01b03821660009081526009602052604090205460ff1615610bfe57610bf7600a601161159e565b9050610ce7565b816001600160a01b0316633d9ea3a16040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3757600080fd5b505afa158015610c4b573d6000803e3d6000fd5b505050506040513d6020811015610c6157600080fd5b50506001600160a01b03821660009081526009602052604081208054600160ff1991821681178355600383018054909216909155810191909155610ca48361160b565b610cad836116e4565b6040516001600160a01b038416907fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90600090a260009150505b919050565b602654604080516304f65f8b60e21b81523060048201526001600160a01b038581166024830152604482018590528251600094859485948594909216926313d97e2c926064808201939291829003018186803b158015610d4b57600080fd5b505afa158015610d5f573d6000803e3d6000fd5b505050506040513d6040811015610d7557600080fd5b5080516020909101519097909650945050505050565b6001600160a01b038116600090815260086020908152604091829020805483518184028101840190945280845260609392830182828015610df557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dd7575b50505050509050919050565b6060600d805480602002602001604051908101604052809291908181526020018280548015610e5957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e3b575b5050505050905090565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b60408051828152602080840282010190915260609082908290828015610f02578160200160208202803883390190505b50905060005b82811015610f5f57610f35868683818110610f1f57fe5b905060200201356001600160a01b0316336117a1565b6013811115610f4057fe5b828281518110610f4c57fe5b6020908102919091010152600101610f08565b50949350505050565b60265460408051630779996560e11b81523060048201526001600160a01b038681166024830152858116604483015260648201859052825160009485948594859490921692630ef332ca926084808201939291829003018186803b158015610fcf57600080fd5b505afa158015610fe3573d6000803e3d6000fd5b505050506040513d6040811015610ff957600080fd5b508051602090910151909890975095505050505050565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b6026546001600160a01b031681565b6008602052816000526040600020818154811061106957fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b61109d82611885565b336000908152602c602090815260408083206001600160a01b038616845290915290205460ff161515811515141561111c576040805162461bcd60e51b815260206004820152601b60248201527f44656c65676174696f6e2073746174757320756e6368616e6765640000000000604482015290519081900360640190fd5b6111273383836118d8565b5050565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526029602052604081208183600881111561117a57fe5b815260208101919091526040016000205460ff169392505050565b60055481565b60006111a8826008611946565b604080516361bfb47160e11b815233600482015290518391600091829182916001600160a01b0386169163c37f68e2916024808301926080929190829003018186803b1580156111f757600080fd5b505afa15801561120b573d6000803e3d6000fd5b505050506040513d608081101561122157600080fd5b50805160208201516040909201519094509092509050821561128a576040805162461bcd60e51b815260206004820152601960248201527f6765744163636f756e74536e617073686f74206661696c656400000000000000604482015290519081900360640190fd5b80156112a75761129c600c600261159e565b945050505050610ce7565b60006112b4873385611995565b905080156112d5576112c9600e600383611a48565b95505050505050610ce7565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff166113145760009650505050505050610ce7565b3360009081526002820160209081526040808320805460ff1916905560089091528120805490915b818110156113f557886001600160a01b031683828154811061135a57fe5b6000918252602090912001546001600160a01b031614156113ed5782600183038154811061138457fe5b9060005260206000200160009054906101000a90046001600160a01b03168382815481106113ae57fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905582546113e7846000198301611cae565b506113f5565b60010161133c565b8181106113fe57fe5b60405133906001600160a01b038b16907fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90600090a360009b9a5050505050505050505050565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156114e35781810151838201526020016114cb565b50505050905090810190601f1680156115105780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561152e57600080fd5b505afa158015611542573d6000803e3d6000fd5b505050506040513d602081101561155857600080fd5b505161159b576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360138111156115cd57fe5b8360178111156115d957fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561160457fe5b9392505050565b600d5460005b8181101561169057826001600160a01b0316600d828154811061163057fe5b6000918252602090912001546001600160a01b03161415611688576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b600101611611565b5050600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b60006116ee611ab6565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b03166117455781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b03166117745780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b60006117ae836007611946565b6001600160a01b03831660009081526009602052604090206117cf81611af7565b6001600160a01b038316600090815260028201602052604090205460ff16156117fc576000915050610b6f565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b6001600160a01b03811661159b576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b038381166000818152602c6020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fcb325b7784f78486e42849c7a50b8c5ee008d00cd90e108a58912c0fcb6288b49281900390910190a3505050565b6119508282611155565b15611127576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b03831660009081526009602052604081206119b690611af7565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166119ef57506000611604565b6000806119ff8587866000611b41565b91935090915060009050826013811115611a1557fe5b14611a2f57816013811115611a2657fe5b92505050611604565b8015611a3c576004611a26565b50600095945050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846013811115611a7757fe5b846017811115611a8357fe5b604080519283526020830191909152818101859052519081900360600190a1836013811115611aae57fe5b949350505050565b6000611af2611ac3611c0f565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b815250611c13565b905090565b805460ff1661159b576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b158015611bb457600080fd5b505afa158015611bc8573d6000803e3d6000fd5b505050506040513d6060811015611bde57600080fd5b50805160208201516040909201519094509092509050826013811115611c0057fe5b9a919950975095505050505050565b4390565b6000816401000000008410611ca65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c6b578181015183820152602001611c53565b50505050905090810190601f168015611c985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b815481835581811115611cd257600083815260209020611cd2918101908301611cd7565b505050565b61099091905b80821115611cf15760008155600101611cdd565b509056fea265627a7a7231582031a37cfa876dad7143b2b39c0288487e4629712e550a7f736e5af6ad6bae2e4064736f6c63430005100032", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103415760003560e01c80639bb27d62116101b8578063c5b4db5511610104578063e37d4b79116100a2578063ede4edd01161007c578063ede4edd014610929578063f445d7031461094f578063f851a4401461097d578063fa6331d81461098557610341565b8063e37d4b79146108cc578063e85a2960146108f2578063e87554461461092157610341565b8063d3270f99116100de578063d3270f9914610860578063dce1544914610868578063dcfbc0c714610894578063ddbf54fd1461089c57610341565b8063c5b4db551461082c578063c5f956af14610850578063c7ee005e1461085857610341565b8063b8324c7c11610171578063bec04f721161014b578063bec04f7214610776578063bf32442d1461077e578063c299823814610786578063c488847b146107f657610341565b8063b8324c7c146106fa578063bb82aa5e14610748578063bbb8864a1461075057610341565b80639bb27d6214610601578063a76b3fda14610609578063a78dc7751461062f578063abfceffc14610674578063b0772d0b146106ea578063b2eafc39146106f257610341565b80634a584432116102925780637dc0d1d0116102305780638e8f294b1161020a5780638e8f294b1461057b5780639254f5e5146105c3578063929fe9a1146105cb57806394b2294b146105f957610341565b80637dc0d1d0146105275780638a7dc1651461052f5780638c1ac18a1461055557610341565b80635dd3fc9d1161026c5780635dd3fc9d146104e9578063719f701b1461050f57806376551383146105175780637d172bd51461051f57610341565b80634a5844321461049e5780634ada90af146104c457806352d84d1e146104cc57610341565b806321af4569116102ff5780632bc7e29e116102d95780632bc7e29e1461043a5780634088c73e1461046057806341a18d2c14610468578063425fad581461049657610341565b806321af45691461040657806324a3d6221461042a578063267822471461043257610341565b80627e3dd21461034657806302c3bcbb1461036257806304ef9d581461039a57806308e0225c146103a25780630db4b4e5146103d057806310b98338146103d8575b600080fd5b61034e61098d565b604080519115158252519081900360200190f35b6103886004803603602081101561037857600080fd5b50356001600160a01b0316610993565b60408051918252519081900360200190f35b6103886109a5565b610388600480360360408110156103b857600080fd5b506001600160a01b03813581169160200135166109ab565b6103886109c8565b61034e600480360360408110156103ee57600080fd5b506001600160a01b03813581169160200135166109ce565b61040e6109ee565b604080516001600160a01b039092168252519081900360200190f35b61040e6109fd565b61040e610a0c565b6103886004803603602081101561045057600080fd5b50356001600160a01b0316610a1b565b61034e610a2d565b6103886004803603604081101561047e57600080fd5b506001600160a01b0381358116916020013516610a36565b61034e610a53565b610388600480360360208110156104b457600080fd5b50356001600160a01b0316610a62565b610388610a74565b61040e600480360360208110156104e257600080fd5b5035610a7a565b610388600480360360208110156104ff57600080fd5b50356001600160a01b0316610aa1565b610388610ab3565b61034e610ab9565b61040e610ac7565b61040e610ad6565b6103886004803603602081101561054557600080fd5b50356001600160a01b0316610ae5565b61034e6004803603602081101561056b57600080fd5b50356001600160a01b0316610af7565b6105a16004803603602081101561059157600080fd5b50356001600160a01b0316610b0c565b6040805193151584526020840192909252151582820152519081900360600190f35b61040e610b32565b61034e600480360360408110156105e157600080fd5b506001600160a01b0381358116916020013516610b41565b610388610b75565b61040e610b7b565b6103886004803603602081101561061f57600080fd5b50356001600160a01b0316610b8a565b61065b6004803603604081101561064557600080fd5b506001600160a01b038135169060200135610cec565b6040805192835260208301919091528051918290030190f35b61069a6004803603602081101561068a57600080fd5b50356001600160a01b0316610d8b565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106d65781810151838201526020016106be565b505050509050019250505060405180910390f35b61069a610e01565b61040e610e63565b6107206004803603602081101561071057600080fd5b50356001600160a01b0316610e72565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61040e610e9c565b6103886004803603602081101561076657600080fd5b50356001600160a01b0316610eab565b610388610ebd565b61040e610ec3565b61069a6004803603602081101561079c57600080fd5b8101906020810181356401000000008111156107b757600080fd5b8201836020820111156107c957600080fd5b803590602001918460208302840111640100000000831117156107eb57600080fd5b509092509050610ed2565b61065b6004803603606081101561080c57600080fd5b506001600160a01b03813581169160208101359091169060400135610f68565b610834611010565b604080516001600160e01b039092168252519081900360200190f35b61040e611023565b61040e611032565b61040e611041565b61040e6004803603604081101561087e57600080fd5b506001600160a01b038135169060200135611050565b61040e611085565b6108ca600480360360408110156108b257600080fd5b506001600160a01b0381351690602001351515611094565b005b610720600480360360208110156108e257600080fd5b50356001600160a01b031661112b565b61034e6004803603604081101561090857600080fd5b5080356001600160a01b0316906020013560ff16611155565b610388611195565b6103886004803603602081101561093f57600080fd5b50356001600160a01b031661119b565b61034e6004803603604081101561096557600080fd5b506001600160a01b0381358116916020013516611445565b61040e611465565b610388611474565b60015b90565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b600d8181548110610a8757fe5b6000918252602090912001546001600160a01b0316905081565b602b6020526000908152604090205481565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff165b92915050565b60075481565b6025546001600160a01b031681565b6000610bca6040518060400160405280601781526020017f5f737570706f72744d61726b657428616464726573732900000000000000000081525061147a565b6001600160a01b03821660009081526009602052604090205460ff1615610bfe57610bf7600a601161159e565b9050610ce7565b816001600160a01b0316633d9ea3a16040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3757600080fd5b505afa158015610c4b573d6000803e3d6000fd5b505050506040513d6020811015610c6157600080fd5b50506001600160a01b03821660009081526009602052604081208054600160ff1991821681178355600383018054909216909155810191909155610ca48361160b565b610cad836116e4565b6040516001600160a01b038416907fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90600090a260009150505b919050565b602654604080516304f65f8b60e21b81523060048201526001600160a01b038581166024830152604482018590528251600094859485948594909216926313d97e2c926064808201939291829003018186803b158015610d4b57600080fd5b505afa158015610d5f573d6000803e3d6000fd5b505050506040513d6040811015610d7557600080fd5b5080516020909101519097909650945050505050565b6001600160a01b038116600090815260086020908152604091829020805483518184028101840190945280845260609392830182828015610df557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dd7575b50505050509050919050565b6060600d805480602002602001604051908101604052809291908181526020018280548015610e5957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e3b575b5050505050905090565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b60408051828152602080840282010190915260609082908290828015610f02578160200160208202803883390190505b50905060005b82811015610f5f57610f35868683818110610f1f57fe5b905060200201356001600160a01b0316336117a1565b6013811115610f4057fe5b828281518110610f4c57fe5b6020908102919091010152600101610f08565b50949350505050565b60265460408051630779996560e11b81523060048201526001600160a01b038681166024830152858116604483015260648201859052825160009485948594859490921692630ef332ca926084808201939291829003018186803b158015610fcf57600080fd5b505afa158015610fe3573d6000803e3d6000fd5b505050506040513d6040811015610ff957600080fd5b508051602090910151909890975095505050505050565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b6026546001600160a01b031681565b6008602052816000526040600020818154811061106957fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b61109d82611885565b336000908152602c602090815260408083206001600160a01b038616845290915290205460ff161515811515141561111c576040805162461bcd60e51b815260206004820152601b60248201527f44656c65676174696f6e2073746174757320756e6368616e6765640000000000604482015290519081900360640190fd5b6111273383836118d8565b5050565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526029602052604081208183600881111561117a57fe5b815260208101919091526040016000205460ff169392505050565b60055481565b60006111a8826008611946565b604080516361bfb47160e11b815233600482015290518391600091829182916001600160a01b0386169163c37f68e2916024808301926080929190829003018186803b1580156111f757600080fd5b505afa15801561120b573d6000803e3d6000fd5b505050506040513d608081101561122157600080fd5b50805160208201516040909201519094509092509050821561128a576040805162461bcd60e51b815260206004820152601960248201527f6765744163636f756e74536e617073686f74206661696c656400000000000000604482015290519081900360640190fd5b80156112a75761129c600c600261159e565b945050505050610ce7565b60006112b4873385611995565b905080156112d5576112c9600e600383611a48565b95505050505050610ce7565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff166113145760009650505050505050610ce7565b3360009081526002820160209081526040808320805460ff1916905560089091528120805490915b818110156113f557886001600160a01b031683828154811061135a57fe5b6000918252602090912001546001600160a01b031614156113ed5782600183038154811061138457fe5b9060005260206000200160009054906101000a90046001600160a01b03168382815481106113ae57fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905582546113e7846000198301611cae565b506113f5565b60010161133c565b8181106113fe57fe5b60405133906001600160a01b038b16907fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90600090a360009b9a5050505050505050505050565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156114e35781810151838201526020016114cb565b50505050905090810190601f1680156115105780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561152e57600080fd5b505afa158015611542573d6000803e3d6000fd5b505050506040513d602081101561155857600080fd5b505161159b576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360138111156115cd57fe5b8360178111156115d957fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561160457fe5b9392505050565b600d5460005b8181101561169057826001600160a01b0316600d828154811061163057fe5b6000918252602090912001546001600160a01b03161415611688576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b600101611611565b5050600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b60006116ee611ab6565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b03166117455781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b03166117745780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b60006117ae836007611946565b6001600160a01b03831660009081526009602052604090206117cf81611af7565b6001600160a01b038316600090815260028201602052604090205460ff16156117fc576000915050610b6f565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b6001600160a01b03811661159b576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b038381166000818152602c6020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fcb325b7784f78486e42849c7a50b8c5ee008d00cd90e108a58912c0fcb6288b49281900390910190a3505050565b6119508282611155565b15611127576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b03831660009081526009602052604081206119b690611af7565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166119ef57506000611604565b6000806119ff8587866000611b41565b91935090915060009050826013811115611a1557fe5b14611a2f57816013811115611a2657fe5b92505050611604565b8015611a3c576004611a26565b50600095945050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846013811115611a7757fe5b846017811115611a8357fe5b604080519283526020830191909152818101859052519081900360600190a1836013811115611aae57fe5b949350505050565b6000611af2611ac3611c0f565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b815250611c13565b905090565b805460ff1661159b576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b158015611bb457600080fd5b505afa158015611bc8573d6000803e3d6000fd5b505050506040513d6060811015611bde57600080fd5b50805160208201516040909201519094509092509050826013811115611c0057fe5b9a919950975095505050505050565b4390565b6000816401000000008410611ca65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c6b578181015183820152602001611c53565b50505050905090810190601f168015611c985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b815481835581811115611cd257600083815260209020611cd2918101908301611cd7565b505050565b61099091905b80821115611cf15760008155600101611cdd565b509056fea265627a7a7231582031a37cfa876dad7143b2b39c0288487e4629712e550a7f736e5af6ad6bae2e4064736f6c63430005100032", + "numDeployments": 3, + "solcInputHash": "ce1a4122e5f4f14eccfd5d8b352422cb", + "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"DelegateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketExited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketListed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketUnlisted\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"_supportMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"checkMembership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"vTokens\",\"type\":\"address[]\"}],\"name\":\"enterMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenAddress\",\"type\":\"address\"}],\"name\":\"exitMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAllMarkets\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAssetsIn\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isComptroller\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateCalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateVAICalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"}],\"name\":\"unlistMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"updateDelegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the methods related to the market's management in the pool\",\"methods\":{\"_supportMarket(address)\":{\"details\":\"Allows a privileged role to add and list markets to the Comptroller\",\"params\":{\"vToken\":\"The address of the market (token) to list\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"checkMembership(address,address)\":{\"params\":{\"account\":\"The address of the account to check\",\"vToken\":\"The vToken to check\"},\"return\":\"True if the account is in the asset, otherwise false\"},\"enterMarkets(address[])\":{\"params\":{\"vTokens\":\"The list of addresses of the vToken markets to be enabled\"},\"return\":\"Success indicator for whether each corresponding market was entered\"},\"exitMarket(address)\":{\"details\":\"Sender must not have an outstanding borrow balance in the asset, or be providing necessary collateral for an outstanding borrow\",\"params\":{\"vTokenAddress\":\"The address of the asset to be removed\"},\"return\":\"Whether or not the account successfully exited the market\"},\"getAllMarkets()\":{\"details\":\"The automatic getter may be used to access an individual market\",\"return\":\"The list of market addresses\"},\"getAssetsIn(address)\":{\"params\":{\"account\":\"The address of the account to pull assets for\"},\"return\":\"A dynamic list with the assets the account has entered\"},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"details\":\"Used in liquidation (called in vToken.liquidateBorrowFresh)\",\"params\":{\"actualRepayAmount\":\"The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\",\"vTokenBorrowed\":\"The address of the borrowed vToken\",\"vTokenCollateral\":\"The address of the collateral vToken\"},\"return\":\"(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\"},\"liquidateVAICalculateSeizeTokens(address,uint256)\":{\"details\":\"Used in liquidation (called in vToken.liquidateBorrowFresh)\",\"params\":{\"actualRepayAmount\":\"The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\",\"vTokenCollateral\":\"The address of the collateral vToken\"},\"return\":\"(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\"},\"unlistMarket(address)\":{\"details\":\"Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0\",\"params\":{\"market\":\"The address of the market (vToken) to unlist\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"updateDelegate(address,bool)\":{\"params\":{\"approved\":\"Whether to grant (true) or revoke (false) the borrowing or redeeming rights\",\"delegate\":\"The address to update the rights for\"}}},\"title\":\"MarketFacet\"},\"userdoc\":{\"methods\":{\"_supportMarket(address)\":{\"notice\":\"Add the market to the markets mapping and set it as listed\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"checkMembership(address,address)\":{\"notice\":\"Returns whether the given account is entered in the given asset\"},\"enterMarkets(address[])\":{\"notice\":\"Add assets to be included in account liquidity calculation\"},\"exitMarket(address)\":{\"notice\":\"Removes asset from sender's account liquidity calculation\"},\"getAllMarkets()\":{\"notice\":\"Return all of the markets\"},\"getAssetsIn(address)\":{\"notice\":\"Returns the assets an account has entered\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"isComptroller()\":{\"notice\":\"Indicator that this is a Comptroller contract (for inspection)\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"liquidateVAICalculateSeizeTokens(address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"unlistMarket(address)\":{\"notice\":\"Unlist a market by setting isListed to false\"},\"updateDelegate(address,bool)\":{\"notice\":\"Grants or revokes the borrowing or redeeming delegate rights to / from an account If allowed, the delegate will be able to borrow funds on behalf of the sender Upon a delegated borrow, the delegate will receive the funds, and the borrower will see the debt on their account Upon a delegated redeem, the delegate will receive the redeemed amount and the approver will see a deduction in his vToken balance\"}},\"notice\":\"This facet contract contains functions regarding markets\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/MarketFacet.sol\":\"MarketFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x06608bb502e91c33fda8c0dd88cc79a49a078fab521bc27d10fc3a69c1da55f4\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/MarketFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { IMarketFacet } from \\\"../interfaces/IMarketFacet.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\n/**\\n * @title MarketFacet\\n * @author Venus\\n * @dev This facet contains all the methods related to the market's management in the pool\\n * @notice This facet contract contains functions regarding markets\\n */\\ncontract MarketFacet is IMarketFacet, FacetBase {\\n /// @notice Emitted when an admin supports a market\\n event MarketListed(VToken indexed vToken);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account\\n event DelegateUpdated(address indexed approver, address indexed delegate, bool approved);\\n\\n /// @notice Emitted when an admin unlists a market\\n event MarketUnlisted(address indexed vToken);\\n\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n function isComptroller() public pure returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Returns the assets an account has entered\\n * @param account The address of the account to pull assets for\\n * @return A dynamic list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n uint256 len;\\n VToken[] memory _accountAssets = accountAssets[account];\\n uint256 _accountAssetsLength = _accountAssets.length;\\n\\n VToken[] memory assetsIn = new VToken[](_accountAssetsLength);\\n\\n for (uint256 i; i < _accountAssetsLength; ++i) {\\n Market memory market = markets[address(_accountAssets[i])];\\n if (market.isListed) {\\n assetsIn[len] = _accountAssets[i];\\n ++len;\\n }\\n }\\n\\n assembly {\\n mstore(assetsIn, len)\\n }\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Return all of the markets\\n * @dev The automatic getter may be used to access an individual market\\n * @return The list of market addresses\\n */\\n function getAllMarkets() external view returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n * @param vTokenBorrowed The address of the borrowed vToken\\n * @param vTokenCollateral The address of the collateral vToken\\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256) {\\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateCalculateSeizeTokens(\\n address(this),\\n vTokenBorrowed,\\n vTokenCollateral,\\n actualRepayAmount\\n );\\n return (err, seizeTokens);\\n }\\n\\n /**\\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n * @param vTokenCollateral The address of the collateral vToken\\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\\n */\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256) {\\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateVAICalculateSeizeTokens(\\n address(this),\\n vTokenCollateral,\\n actualRepayAmount\\n );\\n return (err, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in the given asset\\n * @param account The address of the account to check\\n * @param vToken The vToken to check\\n * @return True if the account is in the asset, otherwise false\\n */\\n function checkMembership(address account, VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].accountMembership[account];\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return Success indicator for whether each corresponding market was entered\\n */\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n results[i] = uint256(addToMarketInternal(VToken(vTokens[i]), msg.sender));\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Unlist a market by setting isListed to false\\n * @dev Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0\\n * @param market The address of the market (vToken) to unlist\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function unlistMarket(address market) external returns (uint256) {\\n ensureAllowed(\\\"unlistMarket(address)\\\");\\n\\n Market storage _market = markets[market];\\n\\n if (!_market.isListed) {\\n return fail(Error.MARKET_NOT_LISTED, FailureInfo.UNLIST_MARKET_NOT_LISTED);\\n }\\n\\n require(actionPaused(market, Action.BORROW), \\\"borrow action is not paused\\\");\\n require(actionPaused(market, Action.MINT), \\\"mint action is not paused\\\");\\n require(actionPaused(market, Action.REDEEM), \\\"redeem action is not paused\\\");\\n require(actionPaused(market, Action.REPAY), \\\"repay action is not paused\\\");\\n require(actionPaused(market, Action.ENTER_MARKET), \\\"enter market action is not paused\\\");\\n require(actionPaused(market, Action.LIQUIDATE), \\\"liquidate action is not paused\\\");\\n require(actionPaused(market, Action.SEIZE), \\\"seize action is not paused\\\");\\n require(actionPaused(market, Action.TRANSFER), \\\"transfer action is not paused\\\");\\n require(actionPaused(market, Action.EXIT_MARKET), \\\"exit market action is not paused\\\");\\n\\n require(borrowCaps[market] == 0, \\\"borrow cap is not 0\\\");\\n require(supplyCaps[market] == 0, \\\"supply cap is not 0\\\");\\n\\n require(_market.collateralFactorMantissa == 0, \\\"collateral factor is not 0\\\");\\n\\n _market.isListed = false;\\n emit MarketUnlisted(market);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation\\n * @dev Sender must not have an outstanding borrow balance in the asset,\\n * or be providing necessary collateral for an outstanding borrow\\n * @param vTokenAddress The address of the asset to be removed\\n * @return Whether or not the account successfully exited the market\\n */\\n function exitMarket(address vTokenAddress) external returns (uint256) {\\n checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 oErr, uint256 tokensHeld, uint256 amountOwed, ) = vToken.getAccountSnapshot(msg.sender);\\n require(oErr == 0, \\\"getAccountSnapshot failed\\\"); // semi-opaque error code\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED);\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n uint256 allowed = redeemAllowedInternal(vTokenAddress, msg.sender, tokensHeld);\\n if (allowed != 0) {\\n return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed);\\n }\\n\\n Market storage marketToExit = markets[address(vToken)];\\n\\n /* Return true if the sender is not already \\u2018in\\u2019 the market */\\n if (!marketToExit.accountMembership[msg.sender]) {\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /* Set vToken account membership to false */\\n delete marketToExit.accountMembership[msg.sender];\\n\\n /* Delete vToken from the account\\u2019s list of assets */\\n // In order to delete vToken, copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n uint256 i;\\n for (; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n userAssetList[i] = userAssetList[len - 1];\\n userAssetList.length--;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(i < len);\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Allows a privileged role to add and list markets to the Comptroller\\n * @param vToken The address of the market (token) to list\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function _supportMarket(VToken vToken) external returns (uint256) {\\n ensureAllowed(\\\"_supportMarket(address)\\\");\\n\\n if (markets[address(vToken)].isListed) {\\n return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS);\\n }\\n\\n vToken.isVToken(); // Sanity check to make sure its really a VToken\\n\\n // Note that isVenus is not in active use anymore\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.isVenus = false;\\n newMarket.collateralFactorMantissa = 0;\\n\\n _addMarketInternal(vToken);\\n _initializeMarket(address(vToken));\\n\\n emit MarketListed(vToken);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account\\n * If allowed, the delegate will be able to borrow funds on behalf of the sender\\n * Upon a delegated borrow, the delegate will receive the funds, and the borrower\\n * will see the debt on their account\\n * Upon a delegated redeem, the delegate will receive the redeemed amount and the approver\\n * will see a deduction in his vToken balance\\n * @param delegate The address to update the rights for\\n * @param approved Whether to grant (true) or revoke (false) the borrowing or redeeming rights\\n */\\n function updateDelegate(address delegate, bool approved) external {\\n ensureNonzeroAddress(delegate);\\n require(approvedDelegates[msg.sender][delegate] != approved, \\\"Delegation status unchanged\\\");\\n\\n _updateDelegate(msg.sender, delegate, approved);\\n }\\n\\n function _updateDelegate(address approver, address delegate, bool approved) internal {\\n approvedDelegates[approver][delegate] = approved;\\n emit DelegateUpdated(approver, delegate, approved);\\n }\\n\\n function _addMarketInternal(VToken vToken) internal {\\n uint256 allMarketsLength = allMarkets.length;\\n for (uint256 i; i < allMarketsLength; ++i) {\\n require(allMarkets[i] != vToken, \\\"already added\\\");\\n }\\n allMarkets.push(vToken);\\n }\\n\\n function _initializeMarket(address vToken) internal {\\n uint32 blockNumber = getBlockNumberAsUint32();\\n\\n VenusMarketState storage supplyState = venusSupplyState[vToken];\\n VenusMarketState storage borrowState = venusBorrowState[vToken];\\n\\n /*\\n * Update market state indices\\n */\\n if (supplyState.index == 0) {\\n // Initialize supply state index with default value\\n supplyState.index = venusInitialIndex;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = venusInitialIndex;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n }\\n}\\n\",\"keccak256\":\"0x23d2725adb9b5eea4fc90f9a7a57e43654d906eaeebb69fcec5a8b7aafc07ebd\"},\"contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface IMarketFacet {\\n function isComptroller() external pure returns (bool);\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256);\\n\\n function checkMembership(address account, VToken vToken) external view returns (bool);\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n function _supportMarket(VToken vToken) external returns (uint256);\\n\\n function getAssetsIn(address account) external view returns (VToken[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function updateDelegate(address delegate, bool allowBorrows) external;\\n\\n function unlistMarket(address market) external returns (uint256);\\n}\\n\",\"keccak256\":\"0xc7745d78ac18b3bea5895d9c3fbf609d541fe0377e475c0f0f41d3527486fce4\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport { VTokenInterface } from \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function mintVAI(uint256 mintVAIAmount) external returns (uint256);\\n\\n function repayVAI(uint256 amount) external returns (uint256, uint256);\\n\\n function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256);\\n\\n function liquidateVAI(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint256, uint256);\\n\\n function getMintableVAI(address minter) external view returns (uint256, uint256);\\n\\n function getVAIAddress() external view returns (address);\\n\\n function getVAIRepayAmount(address account) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x1f020ff46cb0efa0ebf563f449fd4d8aa1c8b8ed53c46860d71a08548d7fdfaa\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK,\\n UNLIST_MARKET_NOT_LISTED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0x4f5a41ef380336395706659e2b8f315870dcf3d617ea6f81104424500b15b1ef\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506123ae806100206000396000f3fe608060405234801561001057600080fd5b506004361061035c5760003560e01c806394b2294b116101d3578063c5b4db5511610104578063e37d4b79116100a2578063ede4edd01161007c578063ede4edd01461096a578063f445d70314610990578063f851a440146109be578063fa6331d8146109c65761035c565b8063e37d4b791461090d578063e85a296014610933578063e8755446146109625761035c565b8063d3270f99116100de578063d3270f99146108a1578063dce15449146108a9578063dcfbc0c7146108d5578063ddbf54fd146108dd5761035c565b8063c5b4db551461086d578063c5f956af14610891578063c7ee005e146108995761035c565b8063b8324c7c11610171578063bec04f721161014b578063bec04f72146107b7578063bf32442d146107bf578063c2998238146107c7578063c488847b146108375761035c565b8063b8324c7c1461073b578063bb82aa5e14610789578063bbb8864a146107915761035c565b8063a78dc775116101ad578063a78dc77514610670578063abfceffc146106b5578063b0772d0b1461072b578063b2eafc39146107335761035c565b806394b2294b1461063a5780639bb27d6214610642578063a76b3fda1461064a5761035c565b8063425fad58116102ad5780637d172bd51161024b5780638c1ac18a116102255780638c1ac18a146105965780638e8f294b146105bc5780639254f5e514610604578063929fe9a11461060c5761035c565b80637d172bd5146105605780637dc0d1d0146105685780638a7dc165146105705761035c565b806352d84d1e1161028757806352d84d1e1461050d5780635dd3fc9d1461052a578063719f701b1461055057806376551383146105585761035c565b8063425fad58146104d75780634a584432146104df5780634ada90af146105055761035c565b806310b983381161031a57806326782247116102f457806326782247146104735780632bc7e29e1461047b5780634088c73e146104a157806341a18d2c146104a95761035c565b806310b983381461041957806321af45691461044757806324a3d6221461046b5761035c565b80627e3dd21461036157806302c3bcbb1461037d57806304ef9d58146103b55780630686dab6146103bd57806308e0225c146103e35780630db4b4e514610411575b600080fd5b6103696109ce565b604080519115158252519081900360200190f35b6103a36004803603602081101561039357600080fd5b50356001600160a01b03166109d4565b60408051918252519081900360200190f35b6103a36109e6565b6103a3600480360360208110156103d357600080fd5b50356001600160a01b03166109ec565b6103a3600480360360408110156103f957600080fd5b506001600160a01b0381358116916020013516610ee0565b6103a3610efd565b6103696004803603604081101561042f57600080fd5b506001600160a01b0381358116916020013516610f03565b61044f610f23565b604080516001600160a01b039092168252519081900360200190f35b61044f610f32565b61044f610f41565b6103a36004803603602081101561049157600080fd5b50356001600160a01b0316610f50565b610369610f62565b6103a3600480360360408110156104bf57600080fd5b506001600160a01b0381358116916020013516610f6b565b610369610f88565b6103a3600480360360208110156104f557600080fd5b50356001600160a01b0316610f97565b6103a3610fa9565b61044f6004803603602081101561052357600080fd5b5035610faf565b6103a36004803603602081101561054057600080fd5b50356001600160a01b0316610fd6565b6103a3610fe8565b610369610fee565b61044f610ffc565b61044f61100b565b6103a36004803603602081101561058657600080fd5b50356001600160a01b031661101a565b610369600480360360208110156105ac57600080fd5b50356001600160a01b031661102c565b6105e2600480360360208110156105d257600080fd5b50356001600160a01b0316611041565b6040805193151584526020840192909252151582820152519081900360600190f35b61044f611067565b6103696004803603604081101561062257600080fd5b506001600160a01b0381358116916020013516611076565b6103a36110aa565b61044f6110b0565b6103a36004803603602081101561066057600080fd5b50356001600160a01b03166110bf565b61069c6004803603604081101561068657600080fd5b506001600160a01b03813516906020013561121d565b6040805192835260208301919091528051918290030190f35b6106db600480360360208110156106cb57600080fd5b50356001600160a01b03166112bc565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156107175781810151838201526020016106ff565b505050509050019250505060405180910390f35b6106db611444565b61044f6114a6565b6107616004803603602081101561075157600080fd5b50356001600160a01b03166114b5565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61044f6114df565b6103a3600480360360208110156107a757600080fd5b50356001600160a01b03166114ee565b6103a3611500565b61044f611506565b6106db600480360360208110156107dd57600080fd5b8101906020810181356401000000008111156107f857600080fd5b82018360208201111561080a57600080fd5b8035906020019184602083028401116401000000008311171561082c57600080fd5b509092509050611515565b61069c6004803603606081101561084d57600080fd5b506001600160a01b038135811691602081013590911690604001356115ab565b610875611653565b604080516001600160e01b039092168252519081900360200190f35b61044f611666565b61044f611675565b61044f611684565b61044f600480360360408110156108bf57600080fd5b506001600160a01b038135169060200135611693565b61044f6116c8565b61090b600480360360408110156108f357600080fd5b506001600160a01b03813516906020013515156116d7565b005b6107616004803603602081101561092357600080fd5b50356001600160a01b031661176e565b6103696004803603604081101561094957600080fd5b5080356001600160a01b0316906020013560ff16611798565b6103a36117d8565b6103a36004803603602081101561098057600080fd5b50356001600160a01b03166117de565b610369600480360360408110156109a657600080fd5b506001600160a01b0381358116916020013516611a88565b61044f611aa8565b6103a3611ab7565b60015b90565b60276020526000908152604090205481565b60225481565b6000610a2460405180604001604052806015815260200174756e6c6973744d61726b657428616464726573732960581b815250611abd565b6001600160a01b0382166000908152600960205260409020805460ff16610a5957610a5160096018611be1565b915050610edb565b610a64836002611798565b610ab5576040805162461bcd60e51b815260206004820152601b60248201527f626f72726f7720616374696f6e206973206e6f74207061757365640000000000604482015290519081900360640190fd5b610ac0836000611798565b610b11576040805162461bcd60e51b815260206004820152601960248201527f6d696e7420616374696f6e206973206e6f742070617573656400000000000000604482015290519081900360640190fd5b610b1c836001611798565b610b6d576040805162461bcd60e51b815260206004820152601b60248201527f72656465656d20616374696f6e206973206e6f74207061757365640000000000604482015290519081900360640190fd5b610b78836003611798565b610bc9576040805162461bcd60e51b815260206004820152601a60248201527f726570617920616374696f6e206973206e6f7420706175736564000000000000604482015290519081900360640190fd5b610bd4836007611798565b610c0f5760405162461bcd60e51b81526004018080602001828103825260218152602001806123596021913960400191505060405180910390fd5b610c1a836005611798565b610c6b576040805162461bcd60e51b815260206004820152601e60248201527f6c697175696461746520616374696f6e206973206e6f74207061757365640000604482015290519081900360640190fd5b610c76836004611798565b610cc7576040805162461bcd60e51b815260206004820152601a60248201527f7365697a6520616374696f6e206973206e6f7420706175736564000000000000604482015290519081900360640190fd5b610cd2836006611798565b610d23576040805162461bcd60e51b815260206004820152601d60248201527f7472616e7366657220616374696f6e206973206e6f7420706175736564000000604482015290519081900360640190fd5b610d2e836008611798565b610d7f576040805162461bcd60e51b815260206004820181905260248201527f65786974206d61726b657420616374696f6e206973206e6f7420706175736564604482015290519081900360640190fd5b6001600160a01b0383166000908152601f602052604090205415610de0576040805162461bcd60e51b81526020600482015260136024820152720626f72726f7720636170206973206e6f74203606c1b604482015290519081900360640190fd5b6001600160a01b03831660009081526027602052604090205415610e41576040805162461bcd60e51b81526020600482015260136024820152720737570706c7920636170206973206e6f74203606c1b604482015290519081900360640190fd5b600181015415610e98576040805162461bcd60e51b815260206004820152601a60248201527f636f6c6c61746572616c20666163746f72206973206e6f742030000000000000604482015290519081900360640190fd5b805460ff191681556040516001600160a01b038416907f302feb03efd5741df80efe7f97f5d93d74d46a542a3d312d0faae64fa1f3e0e990600090a260005b9150505b919050565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b600d8181548110610fbc57fe5b6000918252602090912001546001600160a01b0316905081565b602b6020526000908152604090205481565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff165b92915050565b60075481565b6025546001600160a01b031681565b60006110ff6040518060400160405280601781526020017f5f737570706f72744d61726b6574286164647265737329000000000000000000815250611abd565b6001600160a01b03821660009081526009602052604090205460ff16156111335761112c600a6011611be1565b9050610edb565b816001600160a01b0316633d9ea3a16040518163ffffffff1660e01b815260040160206040518083038186803b15801561116c57600080fd5b505afa158015611180573d6000803e3d6000fd5b505050506040513d602081101561119657600080fd5b50506001600160a01b03821660009081526009602052604081208054600160ff19918216811783556003830180549092169091558101919091556111d983611c4e565b6111e283611d27565b6040516001600160a01b038416907fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90600090a26000610ed7565b602654604080516304f65f8b60e21b81523060048201526001600160a01b038581166024830152604482018590528251600094859485948594909216926313d97e2c926064808201939291829003018186803b15801561127c57600080fd5b505afa158015611290573d6000803e3d6000fd5b505050506040513d60408110156112a657600080fd5b5080516020909101519097909650945050505050565b6001600160a01b0381166000908152600860209081526040808320805482518185028101850190935280835260609493859392919083018282801561132a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161130c575b50505050509050600081519050606081604051908082528060200260200182016040528015611363578160200160208202803883390190505b50905060005b82811015611437576113796122f1565b6009600086848151811061138957fe5b6020908102919091018101516001600160a01b031682528181019290925260409081016000208151606081018352815460ff9081161580158352600184015495830195909552600390920154909116151591810191909152915061142e578482815181106113f357fe5b602002602001015183878151811061140757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508560010195505b50600101611369565b5092835250909392505050565b6060600d80548060200260200160405190810160405280929190818152602001828054801561149c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161147e575b5050505050905090565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b60408051828152602080840282010190915260609082908290828015611545578160200160208202803883390190505b50905060005b828110156115a25761157886868381811061156257fe5b905060200201356001600160a01b031633611de4565b601381111561158357fe5b82828151811061158f57fe5b602090810291909101015260010161154b565b50949350505050565b60265460408051630779996560e11b81523060048201526001600160a01b038681166024830152858116604483015260648201859052825160009485948594859490921692630ef332ca926084808201939291829003018186803b15801561161257600080fd5b505afa158015611626573d6000803e3d6000fd5b505050506040513d604081101561163c57600080fd5b508051602090910151909890975095505050505050565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b6026546001600160a01b031681565b600860205281600052604060002081815481106116ac57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6116e082611ec8565b336000908152602c602090815260408083206001600160a01b038616845290915290205460ff161515811515141561175f576040805162461bcd60e51b815260206004820152601b60248201527f44656c65676174696f6e2073746174757320756e6368616e6765640000000000604482015290519081900360640190fd5b61176a338383611f1b565b5050565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b0382166000908152602960205260408120818360088111156117bd57fe5b815260208101919091526040016000205460ff169392505050565b60055481565b60006117eb826008611f89565b604080516361bfb47160e11b815233600482015290518391600091829182916001600160a01b0386169163c37f68e2916024808301926080929190829003018186803b15801561183a57600080fd5b505afa15801561184e573d6000803e3d6000fd5b505050506040513d608081101561186457600080fd5b5080516020820151604090920151909450909250905082156118cd576040805162461bcd60e51b815260206004820152601960248201527f6765744163636f756e74536e617073686f74206661696c656400000000000000604482015290519081900360640190fd5b80156118ea576118df600c6002611be1565b945050505050610edb565b60006118f7873385611fd8565b905080156119185761190c600e60038361208b565b95505050505050610edb565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff166119575760009650505050505050610edb565b3360009081526002820160209081526040808320805460ff1916905560089091528120805490915b81811015611a3857886001600160a01b031683828154811061199d57fe5b6000918252602090912001546001600160a01b03161415611a30578260018303815481106119c757fe5b9060005260206000200160009054906101000a90046001600160a01b03168382815481106119f157fe5b600091825260209091200180546001600160a01b0319166001600160a01b03929092169190911790558254611a2a846000198301612311565b50611a38565b60010161197f565b818110611a4157fe5b60405133906001600160a01b038b16907fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90600090a360009b9a5050505050505050505050565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b83811015611b26578181015183820152602001611b0e565b50505050905090810190601f168015611b535780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611b7157600080fd5b505afa158015611b85573d6000803e3d6000fd5b505050506040513d6020811015611b9b57600080fd5b5051611bde576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836013811115611c1057fe5b836018811115611c1c57fe5b604080519283526020830191909152600082820152519081900360600190a1826013811115611c4757fe5b9392505050565b600d5460005b81811015611cd357826001600160a01b0316600d8281548110611c7357fe5b6000918252602090912001546001600160a01b03161415611ccb576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b600101611c54565b5050600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b6000611d316120f9565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b0316611d885781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b0316611db75780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b6000611df1836007611f89565b6001600160a01b0383166000908152600960205260409020611e128161213a565b6001600160a01b038316600090815260028201602052604090205460ff1615611e3f5760009150506110a4565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b6001600160a01b038116611bde576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b038381166000818152602c6020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fcb325b7784f78486e42849c7a50b8c5ee008d00cd90e108a58912c0fcb6288b49281900390910190a3505050565b611f938282611798565b1561176a576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260408120611ff99061213a565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff1661203257506000611c47565b6000806120428587866000612184565b9193509091506000905082601381111561205857fe5b146120725781601381111561206957fe5b92505050611c47565b801561207f576004612069565b50600095945050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460138111156120ba57fe5b8460188111156120c657fe5b604080519283526020830191909152818101859052519081900360600190a18360138111156120f157fe5b949350505050565b6000612135612106612252565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b815250612256565b905090565b805460ff16611bde576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b1580156121f757600080fd5b505afa15801561220b573d6000803e3d6000fd5b505050506040513d606081101561222157600080fd5b5080516020820151604090920151909450909250905082601381111561224357fe5b9a919950975095505050505050565b4390565b60008164010000000084106122e95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122ae578181015183820152602001612296565b50505050905090810190601f1680156122db5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b604080516060810182526000808252602082018190529181019190915290565b8154818355818111156123355760008381526020902061233591810190830161233a565b505050565b6109d191905b808211156123545760008155600101612340565b509056fe656e746572206d61726b657420616374696f6e206973206e6f7420706175736564a265627a7a72315820786e558002340aa32adb0cc5ec43fb1f1b66f8437a6cdbac2d0cd7f0d568a32964736f6c63430005100032", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061035c5760003560e01c806394b2294b116101d3578063c5b4db5511610104578063e37d4b79116100a2578063ede4edd01161007c578063ede4edd01461096a578063f445d70314610990578063f851a440146109be578063fa6331d8146109c65761035c565b8063e37d4b791461090d578063e85a296014610933578063e8755446146109625761035c565b8063d3270f99116100de578063d3270f99146108a1578063dce15449146108a9578063dcfbc0c7146108d5578063ddbf54fd146108dd5761035c565b8063c5b4db551461086d578063c5f956af14610891578063c7ee005e146108995761035c565b8063b8324c7c11610171578063bec04f721161014b578063bec04f72146107b7578063bf32442d146107bf578063c2998238146107c7578063c488847b146108375761035c565b8063b8324c7c1461073b578063bb82aa5e14610789578063bbb8864a146107915761035c565b8063a78dc775116101ad578063a78dc77514610670578063abfceffc146106b5578063b0772d0b1461072b578063b2eafc39146107335761035c565b806394b2294b1461063a5780639bb27d6214610642578063a76b3fda1461064a5761035c565b8063425fad58116102ad5780637d172bd51161024b5780638c1ac18a116102255780638c1ac18a146105965780638e8f294b146105bc5780639254f5e514610604578063929fe9a11461060c5761035c565b80637d172bd5146105605780637dc0d1d0146105685780638a7dc165146105705761035c565b806352d84d1e1161028757806352d84d1e1461050d5780635dd3fc9d1461052a578063719f701b1461055057806376551383146105585761035c565b8063425fad58146104d75780634a584432146104df5780634ada90af146105055761035c565b806310b983381161031a57806326782247116102f457806326782247146104735780632bc7e29e1461047b5780634088c73e146104a157806341a18d2c146104a95761035c565b806310b983381461041957806321af45691461044757806324a3d6221461046b5761035c565b80627e3dd21461036157806302c3bcbb1461037d57806304ef9d58146103b55780630686dab6146103bd57806308e0225c146103e35780630db4b4e514610411575b600080fd5b6103696109ce565b604080519115158252519081900360200190f35b6103a36004803603602081101561039357600080fd5b50356001600160a01b03166109d4565b60408051918252519081900360200190f35b6103a36109e6565b6103a3600480360360208110156103d357600080fd5b50356001600160a01b03166109ec565b6103a3600480360360408110156103f957600080fd5b506001600160a01b0381358116916020013516610ee0565b6103a3610efd565b6103696004803603604081101561042f57600080fd5b506001600160a01b0381358116916020013516610f03565b61044f610f23565b604080516001600160a01b039092168252519081900360200190f35b61044f610f32565b61044f610f41565b6103a36004803603602081101561049157600080fd5b50356001600160a01b0316610f50565b610369610f62565b6103a3600480360360408110156104bf57600080fd5b506001600160a01b0381358116916020013516610f6b565b610369610f88565b6103a3600480360360208110156104f557600080fd5b50356001600160a01b0316610f97565b6103a3610fa9565b61044f6004803603602081101561052357600080fd5b5035610faf565b6103a36004803603602081101561054057600080fd5b50356001600160a01b0316610fd6565b6103a3610fe8565b610369610fee565b61044f610ffc565b61044f61100b565b6103a36004803603602081101561058657600080fd5b50356001600160a01b031661101a565b610369600480360360208110156105ac57600080fd5b50356001600160a01b031661102c565b6105e2600480360360208110156105d257600080fd5b50356001600160a01b0316611041565b6040805193151584526020840192909252151582820152519081900360600190f35b61044f611067565b6103696004803603604081101561062257600080fd5b506001600160a01b0381358116916020013516611076565b6103a36110aa565b61044f6110b0565b6103a36004803603602081101561066057600080fd5b50356001600160a01b03166110bf565b61069c6004803603604081101561068657600080fd5b506001600160a01b03813516906020013561121d565b6040805192835260208301919091528051918290030190f35b6106db600480360360208110156106cb57600080fd5b50356001600160a01b03166112bc565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156107175781810151838201526020016106ff565b505050509050019250505060405180910390f35b6106db611444565b61044f6114a6565b6107616004803603602081101561075157600080fd5b50356001600160a01b03166114b5565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61044f6114df565b6103a3600480360360208110156107a757600080fd5b50356001600160a01b03166114ee565b6103a3611500565b61044f611506565b6106db600480360360208110156107dd57600080fd5b8101906020810181356401000000008111156107f857600080fd5b82018360208201111561080a57600080fd5b8035906020019184602083028401116401000000008311171561082c57600080fd5b509092509050611515565b61069c6004803603606081101561084d57600080fd5b506001600160a01b038135811691602081013590911690604001356115ab565b610875611653565b604080516001600160e01b039092168252519081900360200190f35b61044f611666565b61044f611675565b61044f611684565b61044f600480360360408110156108bf57600080fd5b506001600160a01b038135169060200135611693565b61044f6116c8565b61090b600480360360408110156108f357600080fd5b506001600160a01b03813516906020013515156116d7565b005b6107616004803603602081101561092357600080fd5b50356001600160a01b031661176e565b6103696004803603604081101561094957600080fd5b5080356001600160a01b0316906020013560ff16611798565b6103a36117d8565b6103a36004803603602081101561098057600080fd5b50356001600160a01b03166117de565b610369600480360360408110156109a657600080fd5b506001600160a01b0381358116916020013516611a88565b61044f611aa8565b6103a3611ab7565b60015b90565b60276020526000908152604090205481565b60225481565b6000610a2460405180604001604052806015815260200174756e6c6973744d61726b657428616464726573732960581b815250611abd565b6001600160a01b0382166000908152600960205260409020805460ff16610a5957610a5160096018611be1565b915050610edb565b610a64836002611798565b610ab5576040805162461bcd60e51b815260206004820152601b60248201527f626f72726f7720616374696f6e206973206e6f74207061757365640000000000604482015290519081900360640190fd5b610ac0836000611798565b610b11576040805162461bcd60e51b815260206004820152601960248201527f6d696e7420616374696f6e206973206e6f742070617573656400000000000000604482015290519081900360640190fd5b610b1c836001611798565b610b6d576040805162461bcd60e51b815260206004820152601b60248201527f72656465656d20616374696f6e206973206e6f74207061757365640000000000604482015290519081900360640190fd5b610b78836003611798565b610bc9576040805162461bcd60e51b815260206004820152601a60248201527f726570617920616374696f6e206973206e6f7420706175736564000000000000604482015290519081900360640190fd5b610bd4836007611798565b610c0f5760405162461bcd60e51b81526004018080602001828103825260218152602001806123596021913960400191505060405180910390fd5b610c1a836005611798565b610c6b576040805162461bcd60e51b815260206004820152601e60248201527f6c697175696461746520616374696f6e206973206e6f74207061757365640000604482015290519081900360640190fd5b610c76836004611798565b610cc7576040805162461bcd60e51b815260206004820152601a60248201527f7365697a6520616374696f6e206973206e6f7420706175736564000000000000604482015290519081900360640190fd5b610cd2836006611798565b610d23576040805162461bcd60e51b815260206004820152601d60248201527f7472616e7366657220616374696f6e206973206e6f7420706175736564000000604482015290519081900360640190fd5b610d2e836008611798565b610d7f576040805162461bcd60e51b815260206004820181905260248201527f65786974206d61726b657420616374696f6e206973206e6f7420706175736564604482015290519081900360640190fd5b6001600160a01b0383166000908152601f602052604090205415610de0576040805162461bcd60e51b81526020600482015260136024820152720626f72726f7720636170206973206e6f74203606c1b604482015290519081900360640190fd5b6001600160a01b03831660009081526027602052604090205415610e41576040805162461bcd60e51b81526020600482015260136024820152720737570706c7920636170206973206e6f74203606c1b604482015290519081900360640190fd5b600181015415610e98576040805162461bcd60e51b815260206004820152601a60248201527f636f6c6c61746572616c20666163746f72206973206e6f742030000000000000604482015290519081900360640190fd5b805460ff191681556040516001600160a01b038416907f302feb03efd5741df80efe7f97f5d93d74d46a542a3d312d0faae64fa1f3e0e990600090a260005b9150505b919050565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b600d8181548110610fbc57fe5b6000918252602090912001546001600160a01b0316905081565b602b6020526000908152604090205481565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff165b92915050565b60075481565b6025546001600160a01b031681565b60006110ff6040518060400160405280601781526020017f5f737570706f72744d61726b6574286164647265737329000000000000000000815250611abd565b6001600160a01b03821660009081526009602052604090205460ff16156111335761112c600a6011611be1565b9050610edb565b816001600160a01b0316633d9ea3a16040518163ffffffff1660e01b815260040160206040518083038186803b15801561116c57600080fd5b505afa158015611180573d6000803e3d6000fd5b505050506040513d602081101561119657600080fd5b50506001600160a01b03821660009081526009602052604081208054600160ff19918216811783556003830180549092169091558101919091556111d983611c4e565b6111e283611d27565b6040516001600160a01b038416907fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90600090a26000610ed7565b602654604080516304f65f8b60e21b81523060048201526001600160a01b038581166024830152604482018590528251600094859485948594909216926313d97e2c926064808201939291829003018186803b15801561127c57600080fd5b505afa158015611290573d6000803e3d6000fd5b505050506040513d60408110156112a657600080fd5b5080516020909101519097909650945050505050565b6001600160a01b0381166000908152600860209081526040808320805482518185028101850190935280835260609493859392919083018282801561132a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161130c575b50505050509050600081519050606081604051908082528060200260200182016040528015611363578160200160208202803883390190505b50905060005b82811015611437576113796122f1565b6009600086848151811061138957fe5b6020908102919091018101516001600160a01b031682528181019290925260409081016000208151606081018352815460ff9081161580158352600184015495830195909552600390920154909116151591810191909152915061142e578482815181106113f357fe5b602002602001015183878151811061140757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508560010195505b50600101611369565b5092835250909392505050565b6060600d80548060200260200160405190810160405280929190818152602001828054801561149c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161147e575b5050505050905090565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b60408051828152602080840282010190915260609082908290828015611545578160200160208202803883390190505b50905060005b828110156115a25761157886868381811061156257fe5b905060200201356001600160a01b031633611de4565b601381111561158357fe5b82828151811061158f57fe5b602090810291909101015260010161154b565b50949350505050565b60265460408051630779996560e11b81523060048201526001600160a01b038681166024830152858116604483015260648201859052825160009485948594859490921692630ef332ca926084808201939291829003018186803b15801561161257600080fd5b505afa158015611626573d6000803e3d6000fd5b505050506040513d604081101561163c57600080fd5b508051602090910151909890975095505050505050565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b6026546001600160a01b031681565b600860205281600052604060002081815481106116ac57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6116e082611ec8565b336000908152602c602090815260408083206001600160a01b038616845290915290205460ff161515811515141561175f576040805162461bcd60e51b815260206004820152601b60248201527f44656c65676174696f6e2073746174757320756e6368616e6765640000000000604482015290519081900360640190fd5b61176a338383611f1b565b5050565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b0382166000908152602960205260408120818360088111156117bd57fe5b815260208101919091526040016000205460ff169392505050565b60055481565b60006117eb826008611f89565b604080516361bfb47160e11b815233600482015290518391600091829182916001600160a01b0386169163c37f68e2916024808301926080929190829003018186803b15801561183a57600080fd5b505afa15801561184e573d6000803e3d6000fd5b505050506040513d608081101561186457600080fd5b5080516020820151604090920151909450909250905082156118cd576040805162461bcd60e51b815260206004820152601960248201527f6765744163636f756e74536e617073686f74206661696c656400000000000000604482015290519081900360640190fd5b80156118ea576118df600c6002611be1565b945050505050610edb565b60006118f7873385611fd8565b905080156119185761190c600e60038361208b565b95505050505050610edb565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff166119575760009650505050505050610edb565b3360009081526002820160209081526040808320805460ff1916905560089091528120805490915b81811015611a3857886001600160a01b031683828154811061199d57fe5b6000918252602090912001546001600160a01b03161415611a30578260018303815481106119c757fe5b9060005260206000200160009054906101000a90046001600160a01b03168382815481106119f157fe5b600091825260209091200180546001600160a01b0319166001600160a01b03929092169190911790558254611a2a846000198301612311565b50611a38565b60010161197f565b818110611a4157fe5b60405133906001600160a01b038b16907fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90600090a360009b9a5050505050505050505050565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b83811015611b26578181015183820152602001611b0e565b50505050905090810190601f168015611b535780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611b7157600080fd5b505afa158015611b85573d6000803e3d6000fd5b505050506040513d6020811015611b9b57600080fd5b5051611bde576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836013811115611c1057fe5b836018811115611c1c57fe5b604080519283526020830191909152600082820152519081900360600190a1826013811115611c4757fe5b9392505050565b600d5460005b81811015611cd357826001600160a01b0316600d8281548110611c7357fe5b6000918252602090912001546001600160a01b03161415611ccb576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b600101611c54565b5050600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b6000611d316120f9565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b0316611d885781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b0316611db75780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b6000611df1836007611f89565b6001600160a01b0383166000908152600960205260409020611e128161213a565b6001600160a01b038316600090815260028201602052604090205460ff1615611e3f5760009150506110a4565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b6001600160a01b038116611bde576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b038381166000818152602c6020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fcb325b7784f78486e42849c7a50b8c5ee008d00cd90e108a58912c0fcb6288b49281900390910190a3505050565b611f938282611798565b1561176a576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260408120611ff99061213a565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff1661203257506000611c47565b6000806120428587866000612184565b9193509091506000905082601381111561205857fe5b146120725781601381111561206957fe5b92505050611c47565b801561207f576004612069565b50600095945050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460138111156120ba57fe5b8460188111156120c657fe5b604080519283526020830191909152818101859052519081900360600190a18360138111156120f157fe5b949350505050565b6000612135612106612252565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b815250612256565b905090565b805460ff16611bde576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b1580156121f757600080fd5b505afa15801561220b573d6000803e3d6000fd5b505050506040513d606081101561222157600080fd5b5080516020820151604090920151909450909250905082601381111561224357fe5b9a919950975095505050505050565b4390565b60008164010000000084106122e95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122ae578181015183820152602001612296565b50505050905090810190601f1680156122db5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b604080516060810182526000808252602082018190529181019190915290565b8154818355818111156123355760008381526020902061233591810190830161233a565b505050565b6109d191905b808211156123545760008155600101612340565b509056fe656e746572206d61726b657420616374696f6e206973206e6f7420706175736564a265627a7a72315820786e558002340aa32adb0cc5ec43fb1f1b66f8437a6cdbac2d0cd7f0d568a32964736f6c63430005100032", "devdoc": { "author": "Venus", "details": "This facet contains all the methods related to the market's management in the pool", @@ -1244,6 +1278,13 @@ }, "return": "(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)" }, + "unlistMarket(address)": { + "details": "Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0", + "params": { + "market": "The address of the market (vToken) to unlist" + }, + "return": "uint256 0=success, otherwise a failure. (See enum Error for details)" + }, "updateDelegate(address,bool)": { "params": { "approved": "Whether to grant (true) or revoke (false) the borrowing or redeeming rights", @@ -1288,6 +1329,9 @@ "liquidateVAICalculateSeizeTokens(address,uint256)": { "notice": "Calculate number of tokens of collateral asset to seize given an underlying amount" }, + "unlistMarket(address)": { + "notice": "Unlist a market by setting isListed to false" + }, "updateDelegate(address,bool)": { "notice": "Grants or revokes the borrowing or redeeming delegate rights to / from an account If allowed, the delegate will be able to borrow funds on behalf of the sender Upon a delegated borrow, the delegate will receive the funds, and the borrower will see the debt on their account Upon a delegated redeem, the delegate will receive the redeemed amount and the approver will see a deduction in his vToken balance" } @@ -1297,7 +1341,7 @@ "storageLayout": { "storage": [ { - "astId": 2402, + "astId": 2503, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "admin", "offset": 0, @@ -1305,7 +1349,7 @@ "type": "t_address" }, { - "astId": 2404, + "astId": 2505, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "pendingAdmin", "offset": 0, @@ -1313,7 +1357,7 @@ "type": "t_address" }, { - "astId": 2406, + "astId": 2507, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "comptrollerImplementation", "offset": 0, @@ -1321,7 +1365,7 @@ "type": "t_address" }, { - "astId": 2408, + "astId": 2509, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "pendingComptrollerImplementation", "offset": 0, @@ -1329,15 +1373,15 @@ "type": "t_address" }, { - "astId": 2415, + "astId": 2516, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "oracle", "offset": 0, "slot": "4", - "type": "t_contract(PriceOracle)12106" + "type": "t_contract(PriceOracle)12346" }, { - "astId": 2417, + "astId": 2518, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "closeFactorMantissa", "offset": 0, @@ -1345,7 +1389,7 @@ "type": "t_uint256" }, { - "astId": 2419, + "astId": 2520, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "liquidationIncentiveMantissa", "offset": 0, @@ -1353,7 +1397,7 @@ "type": "t_uint256" }, { - "astId": 2421, + "astId": 2522, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "maxAssets", "offset": 0, @@ -1361,23 +1405,23 @@ "type": "t_uint256" }, { - "astId": 2426, + "astId": 2527, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "accountAssets", "offset": 0, "slot": "8", - "type": "t_mapping(t_address,t_array(t_contract(VToken)23033)dyn_storage)" + "type": "t_mapping(t_address,t_array(t_contract(VToken)23484)dyn_storage)" }, { - "astId": 2441, + "astId": 2542, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "markets", "offset": 0, "slot": "9", - "type": "t_mapping(t_address,t_struct(Market)2437_storage)" + "type": "t_mapping(t_address,t_struct(Market)2538_storage)" }, { - "astId": 2443, + "astId": 2544, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "pauseGuardian", "offset": 0, @@ -1385,7 +1429,7 @@ "type": "t_address" }, { - "astId": 2445, + "astId": 2546, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_mintGuardianPaused", "offset": 20, @@ -1393,7 +1437,7 @@ "type": "t_bool" }, { - "astId": 2447, + "astId": 2548, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_borrowGuardianPaused", "offset": 21, @@ -1401,7 +1445,7 @@ "type": "t_bool" }, { - "astId": 2449, + "astId": 2550, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "transferGuardianPaused", "offset": 22, @@ -1409,7 +1453,7 @@ "type": "t_bool" }, { - "astId": 2451, + "astId": 2552, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "seizeGuardianPaused", "offset": 23, @@ -1417,7 +1461,7 @@ "type": "t_bool" }, { - "astId": 2455, + "astId": 2556, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "mintGuardianPaused", "offset": 0, @@ -1425,7 +1469,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2459, + "astId": 2560, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "borrowGuardianPaused", "offset": 0, @@ -1433,15 +1477,15 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2467, + "astId": 2568, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "allMarkets", "offset": 0, "slot": "13", - "type": "t_array(t_contract(VToken)23033)dyn_storage" + "type": "t_array(t_contract(VToken)23484)dyn_storage" }, { - "astId": 2469, + "astId": 2570, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusRate", "offset": 0, @@ -1449,7 +1493,7 @@ "type": "t_uint256" }, { - "astId": 2473, + "astId": 2574, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusSpeeds", "offset": 0, @@ -1457,23 +1501,23 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2477, + "astId": 2578, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusSupplyState", "offset": 0, "slot": "16", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)" }, { - "astId": 2481, + "astId": 2582, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusBorrowState", "offset": 0, "slot": "17", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)" }, { - "astId": 2487, + "astId": 2588, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusSupplierIndex", "offset": 0, @@ -1481,7 +1525,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2493, + "astId": 2594, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusBorrowerIndex", "offset": 0, @@ -1489,7 +1533,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2497, + "astId": 2598, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusAccrued", "offset": 0, @@ -1497,15 +1541,15 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2499, + "astId": 2600, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "vaiController", "offset": 0, "slot": "21", - "type": "t_contract(VAIControllerInterface)15582" + "type": "t_contract(VAIControllerInterface)15644" }, { - "astId": 2503, + "astId": 2604, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "mintedVAIs", "offset": 0, @@ -1513,7 +1557,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2505, + "astId": 2606, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "vaiMintRate", "offset": 0, @@ -1521,7 +1565,7 @@ "type": "t_uint256" }, { - "astId": 2507, + "astId": 2608, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "mintVAIGuardianPaused", "offset": 0, @@ -1529,7 +1573,7 @@ "type": "t_bool" }, { - "astId": 2509, + "astId": 2610, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "repayVAIGuardianPaused", "offset": 1, @@ -1537,7 +1581,7 @@ "type": "t_bool" }, { - "astId": 2511, + "astId": 2612, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "protocolPaused", "offset": 2, @@ -1545,7 +1589,7 @@ "type": "t_bool" }, { - "astId": 2513, + "astId": 2614, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusVAIRate", "offset": 0, @@ -1553,7 +1597,7 @@ "type": "t_uint256" }, { - "astId": 2518, + "astId": 2619, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusVAIVaultRate", "offset": 0, @@ -1561,7 +1605,7 @@ "type": "t_uint256" }, { - "astId": 2520, + "astId": 2621, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "vaiVaultAddress", "offset": 0, @@ -1569,7 +1613,7 @@ "type": "t_address" }, { - "astId": 2522, + "astId": 2623, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "releaseStartBlock", "offset": 0, @@ -1577,7 +1621,7 @@ "type": "t_uint256" }, { - "astId": 2524, + "astId": 2625, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "minReleaseAmount", "offset": 0, @@ -1585,7 +1629,7 @@ "type": "t_uint256" }, { - "astId": 2529, + "astId": 2630, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "borrowCapGuardian", "offset": 0, @@ -1593,7 +1637,7 @@ "type": "t_address" }, { - "astId": 2533, + "astId": 2634, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "borrowCaps", "offset": 0, @@ -1601,7 +1645,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2538, + "astId": 2639, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "treasuryGuardian", "offset": 0, @@ -1609,7 +1653,7 @@ "type": "t_address" }, { - "astId": 2540, + "astId": 2641, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "treasuryAddress", "offset": 0, @@ -1617,7 +1661,7 @@ "type": "t_address" }, { - "astId": 2542, + "astId": 2643, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "treasuryPercent", "offset": 0, @@ -1625,7 +1669,7 @@ "type": "t_uint256" }, { - "astId": 2549, + "astId": 2650, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusContributorSpeeds", "offset": 0, @@ -1633,7 +1677,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2553, + "astId": 2654, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "lastContributorBlock", "offset": 0, @@ -1641,7 +1685,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2558, + "astId": 2659, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "liquidatorContract", "offset": 0, @@ -1649,15 +1693,15 @@ "type": "t_address" }, { - "astId": 2563, + "astId": 2664, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "comptrollerLens", "offset": 0, "slot": "38", - "type": "t_contract(ComptrollerLensInterface)2377" + "type": "t_contract(ComptrollerLensInterface)2478" }, { - "astId": 2570, + "astId": 2671, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "supplyCaps", "offset": 0, @@ -1665,7 +1709,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2575, + "astId": 2676, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "accessControl", "offset": 0, @@ -1673,7 +1717,7 @@ "type": "t_address" }, { - "astId": 2581, + "astId": 2682, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_actionPaused", "offset": 0, @@ -1681,7 +1725,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" }, { - "astId": 2588, + "astId": 2689, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusBorrowSpeeds", "offset": 0, @@ -1689,7 +1733,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2592, + "astId": 2693, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusSupplySpeeds", "offset": 0, @@ -1697,7 +1741,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2601, + "astId": 2702, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "approvedDelegates", "offset": 0, @@ -1705,7 +1749,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2608, + "astId": 2709, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "isForcedLiquidationEnabled", "offset": 0, @@ -1713,23 +1757,23 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2626, + "astId": 2727, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_selectorToFacetAndPosition", "offset": 0, "slot": "46", - "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2616_storage)" + "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2717_storage)" }, { - "astId": 2630, + "astId": 2731, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_facetFunctionSelectors", "offset": 0, "slot": "47", - "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2622_storage)" + "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2723_storage)" }, { - "astId": 2633, + "astId": 2734, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_facetAddresses", "offset": 0, @@ -1737,15 +1781,15 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 2638, + "astId": 2739, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "prime", "offset": 0, "slot": "49", - "type": "t_contract(IPrime)12283" + "type": "t_contract(IPrime)12523" }, { - "astId": 2647, + "astId": 2748, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "isForcedLiquidationEnabledForUser", "offset": 0, @@ -1753,7 +1797,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2652, + "astId": 2753, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "xvs", "offset": 0, @@ -1761,7 +1805,7 @@ "type": "t_address" }, { - "astId": 2654, + "astId": 2755, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "xvsVToken", "offset": 0, @@ -1787,8 +1831,8 @@ "label": "bytes4[]", "numberOfBytes": "32" }, - "t_array(t_contract(VToken)23033)dyn_storage": { - "base": "t_contract(VToken)23033", + "t_array(t_contract(VToken)23484)dyn_storage": { + "base": "t_contract(VToken)23484", "encoding": "dynamic_array", "label": "contract VToken[]", "numberOfBytes": "32" @@ -1803,37 +1847,37 @@ "label": "bytes4", "numberOfBytes": "4" }, - "t_contract(ComptrollerLensInterface)2377": { + "t_contract(ComptrollerLensInterface)2478": { "encoding": "inplace", "label": "contract ComptrollerLensInterface", "numberOfBytes": "20" }, - "t_contract(IPrime)12283": { + "t_contract(IPrime)12523": { "encoding": "inplace", "label": "contract IPrime", "numberOfBytes": "20" }, - "t_contract(PriceOracle)12106": { + "t_contract(PriceOracle)12346": { "encoding": "inplace", "label": "contract PriceOracle", "numberOfBytes": "20" }, - "t_contract(VAIControllerInterface)15582": { + "t_contract(VAIControllerInterface)15644": { "encoding": "inplace", "label": "contract VAIControllerInterface", "numberOfBytes": "20" }, - "t_contract(VToken)23033": { + "t_contract(VToken)23484": { "encoding": "inplace", "label": "contract VToken", "numberOfBytes": "20" }, - "t_mapping(t_address,t_array(t_contract(VToken)23033)dyn_storage)": { + "t_mapping(t_address,t_array(t_contract(VToken)23484)dyn_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => contract VToken[])", "numberOfBytes": "32", - "value": "t_array(t_contract(VToken)23033)dyn_storage" + "value": "t_array(t_contract(VToken)23484)dyn_storage" }, "t_mapping(t_address,t_bool)": { "encoding": "mapping", @@ -1863,26 +1907,26 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_bool)" }, - "t_mapping(t_address,t_struct(FacetFunctionSelectors)2622_storage)": { + "t_mapping(t_address,t_struct(FacetFunctionSelectors)2723_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV13Storage.FacetFunctionSelectors)", "numberOfBytes": "32", - "value": "t_struct(FacetFunctionSelectors)2622_storage" + "value": "t_struct(FacetFunctionSelectors)2723_storage" }, - "t_mapping(t_address,t_struct(Market)2437_storage)": { + "t_mapping(t_address,t_struct(Market)2538_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.Market)", "numberOfBytes": "32", - "value": "t_struct(Market)2437_storage" + "value": "t_struct(Market)2538_storage" }, - "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)": { + "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.VenusMarketState)", "numberOfBytes": "32", - "value": "t_struct(VenusMarketState)2464_storage" + "value": "t_struct(VenusMarketState)2565_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1891,12 +1935,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2616_storage)": { + "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2717_storage)": { "encoding": "mapping", "key": "t_bytes4", "label": "mapping(bytes4 => struct ComptrollerV13Storage.FacetAddressAndPosition)", "numberOfBytes": "32", - "value": "t_struct(FacetAddressAndPosition)2616_storage" + "value": "t_struct(FacetAddressAndPosition)2717_storage" }, "t_mapping(t_uint256,t_bool)": { "encoding": "mapping", @@ -1905,12 +1949,12 @@ "numberOfBytes": "32", "value": "t_bool" }, - "t_struct(FacetAddressAndPosition)2616_storage": { + "t_struct(FacetAddressAndPosition)2717_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetAddressAndPosition", "members": [ { - "astId": 2613, + "astId": 2714, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "facetAddress", "offset": 0, @@ -1918,7 +1962,7 @@ "type": "t_address" }, { - "astId": 2615, + "astId": 2716, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "functionSelectorPosition", "offset": 20, @@ -1928,12 +1972,12 @@ ], "numberOfBytes": "32" }, - "t_struct(FacetFunctionSelectors)2622_storage": { + "t_struct(FacetFunctionSelectors)2723_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetFunctionSelectors", "members": [ { - "astId": 2619, + "astId": 2720, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "functionSelectors", "offset": 0, @@ -1941,7 +1985,7 @@ "type": "t_array(t_bytes4)dyn_storage" }, { - "astId": 2621, + "astId": 2722, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "facetAddressPosition", "offset": 0, @@ -1951,12 +1995,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Market)2437_storage": { + "t_struct(Market)2538_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.Market", "members": [ { - "astId": 2428, + "astId": 2529, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "isListed", "offset": 0, @@ -1964,7 +2008,7 @@ "type": "t_bool" }, { - "astId": 2430, + "astId": 2531, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "collateralFactorMantissa", "offset": 0, @@ -1972,7 +2016,7 @@ "type": "t_uint256" }, { - "astId": 2434, + "astId": 2535, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "accountMembership", "offset": 0, @@ -1980,7 +2024,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2436, + "astId": 2537, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "isVenus", "offset": 0, @@ -1990,12 +2034,12 @@ ], "numberOfBytes": "128" }, - "t_struct(VenusMarketState)2464_storage": { + "t_struct(VenusMarketState)2565_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.VenusMarketState", "members": [ { - "astId": 2461, + "astId": 2562, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "index", "offset": 0, @@ -2003,7 +2047,7 @@ "type": "t_uint224" }, { - "astId": 2463, + "astId": 2564, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "block", "offset": 28, diff --git a/deployments/bscmainnet/PolicyFacet.json b/deployments/bscmainnet/PolicyFacet.json index a15ef9ad5..1a5295b51 100644 --- a/deployments/bscmainnet/PolicyFacet.json +++ b/deployments/bscmainnet/PolicyFacet.json @@ -1,5 +1,5 @@ { - "address": "0x95CC56f266BC95Ae2486cb0cFeda1054B4aA4086", + "address": "0x93e7Ff7c87B496aE76fFb22d437c9d46461A9B51", "abi": [ { "anonymous": false, @@ -1545,28 +1545,28 @@ "type": "function" } ], - "transactionHash": "0x041f4f9603e19067b52b728102bf4a9ef1aad85520576b31d5dae68e33cb832b", + "transactionHash": "0xf69d0ed3318c35e8cc67f407debb551785e4331f8e3f4c4b275ef2be5c016b96", "receipt": { "to": null, - "from": "0x7Bf1Fe2C42E79dbA813Bf5026B7720935a55ec5f", - "contractAddress": "0x95CC56f266BC95Ae2486cb0cFeda1054B4aA4086", - "transactionIndex": 98, - "gasUsed": "3056070", + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x93e7Ff7c87B496aE76fFb22d437c9d46461A9B51", + "transactionIndex": 107, + "gasUsed": "3072721", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x97479420bfdb28f45335e3a4143cd1b67ea6f5ec38bbce5656e7be8a15a6695f", - "transactionHash": "0x041f4f9603e19067b52b728102bf4a9ef1aad85520576b31d5dae68e33cb832b", + "blockHash": "0x11070405758a3c29f66863fc48e04491d2e85216f352aba736ab04bbb294dc4f", + "transactionHash": "0xf69d0ed3318c35e8cc67f407debb551785e4331f8e3f4c4b275ef2be5c016b96", "logs": [], - "blockNumber": 36961179, - "cumulativeGasUsed": "12234138", + "blockNumber": 39374390, + "cumulativeGasUsed": "13173258", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "ad834ffdd224ebe1944f429cc9972360", - "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusDelta\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusBorrowIndex\",\"type\":\"uint256\"}],\"name\":\"DistributedBorrowerVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"supplier\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusDelta\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusSupplyIndex\",\"type\":\"uint256\"}],\"name\":\"DistributedSupplierVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"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\":false,\"internalType\":\"uint256\",\"name\":\"newSpeed\",\"type\":\"uint256\"}],\"name\":\"VenusBorrowSpeedUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSpeed\",\"type\":\"uint256\"}],\"name\":\"VenusSupplySpeedUpdated\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"supplySpeeds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"borrowSpeeds\",\"type\":\"uint256[]\"}],\"name\":\"_setVenusSpeeds\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"borrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"borrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenModify\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"getHypotheticalAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateBorrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"liquidateBorrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"mintAmount\",\"type\":\"uint256\"}],\"name\":\"mintAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualMintAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mintTokens\",\"type\":\"uint256\"}],\"name\":\"mintVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"redeemAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"redeemVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"name\":\"repayBorrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowerIndex\",\"type\":\"uint256\"}],\"name\":\"repayBorrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"seizeAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"seizeVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"transferAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"transferVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the hooks used while transferring the assets\",\"methods\":{\"_setVenusSpeeds(address[],uint256[],uint256[])\":{\"details\":\"Allows the contract admin to set XVS speed for a market\",\"params\":{\"borrowSpeeds\":\"New XVS speed for borrow\",\"supplySpeeds\":\"New XVS speed for supply\",\"vTokens\":\"The market whose XVS speed to update\"}},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"borrowAllowed(address,address,uint256)\":{\"params\":{\"borrowAmount\":\"The amount of underlying the account would borrow\",\"borrower\":\"The account which would borrow the asset\",\"vToken\":\"The market to verify the borrow against\"},\"return\":\"0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"borrowVerify(address,address,uint256)\":{\"params\":{\"borrowAmount\":\"The amount of the underlying asset requested to borrow\",\"borrower\":\"The address borrowing the underlying\",\"vToken\":\"Asset whose underlying is being borrowed\"}},\"getAccountLiquidity(address)\":{\"return\":\"(possible error code (semi-opaque), account liquidity in excess of collateral requirements, account shortfall below collateral requirements)\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"params\":{\"account\":\"The account to determine liquidity for\",\"borrowAmount\":\"The amount of underlying to hypothetically borrow\",\"redeemTokens\":\"The number of tokens to hypothetically redeem\",\"vTokenModify\":\"The market to hypothetically redeem/borrow in\"},\"return\":\"(possible error code (semi-opaque), hypothetical account liquidity in excess of collateral requirements, hypothetical account shortfall below collateral requirements)\"},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"liquidateBorrowAllowed(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"repayAmount\":\"The amount of underlying being repaid\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"liquidateBorrowVerify(address,address,address,address,uint256,uint256)\":{\"params\":{\"actualRepayAmount\":\"The amount of underlying being repaid\",\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The amount of collateral token that will be seized\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"mintAllowed(address,address,uint256)\":{\"params\":{\"mintAmount\":\"The amount of underlying being supplied to the market in exchange for tokens\",\"minter\":\"The account which would get the minted tokens\",\"vToken\":\"The market to verify the mint against\"},\"return\":\"0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"mintVerify(address,address,uint256,uint256)\":{\"params\":{\"actualMintAmount\":\"The amount of the underlying asset being minted\",\"mintTokens\":\"The number of tokens being minted\",\"minter\":\"The address minting the tokens\",\"vToken\":\"Asset being minted\"}},\"redeemAllowed(address,address,uint256)\":{\"params\":{\"redeemTokens\":\"The number of vTokens to exchange for the underlying asset in the market\",\"redeemer\":\"The account which would redeem the tokens\",\"vToken\":\"The market to verify the redeem against\"},\"return\":\"0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"redeemVerify(address,address,uint256,uint256)\":{\"params\":{\"redeemAmount\":\"The amount of the underlying asset being redeemed\",\"redeemTokens\":\"The number of tokens being redeemed\",\"redeemer\":\"The address redeeming the tokens\",\"vToken\":\"Asset being redeemed\"}},\"repayBorrowAllowed(address,address,address,uint256)\":{\"params\":{\"borrower\":\"The account which borrowed the asset\",\"payer\":\"The account which would repay the asset\",\"repayAmount\":\"The amount of the underlying asset the account would repay\",\"vToken\":\"The market to verify the repay against\"},\"return\":\"0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"repayBorrowVerify(address,address,address,uint256,uint256)\":{\"params\":{\"actualRepayAmount\":\"The amount of underlying being repaid\",\"borrower\":\"The address of the borrower\",\"payer\":\"The address repaying the borrow\",\"vToken\":\"Asset being repaid\"}},\"seizeAllowed(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The number of collateral tokens to seize\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"seizeVerify(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The number of collateral tokens to seize\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"transferAllowed(address,address,address,uint256)\":{\"params\":{\"dst\":\"The account which receives the tokens\",\"src\":\"The account which sources the tokens\",\"transferTokens\":\"The number of vTokens to transfer\",\"vToken\":\"The market to verify the transfer against\"},\"return\":\"0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"transferVerify(address,address,address,uint256)\":{\"params\":{\"dst\":\"The account which receives the tokens\",\"src\":\"The account which sources the tokens\",\"transferTokens\":\"The number of vTokens to transfer\",\"vToken\":\"Asset being transferred\"}}},\"title\":\"PolicyFacet\"},\"userdoc\":{\"methods\":{\"_setVenusSpeeds(address[],uint256[],uint256[])\":{\"notice\":\"Set XVS speed for a single market\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"borrowAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to borrow the underlying asset of the given market\"},\"borrowVerify(address,address,uint256)\":{\"notice\":\"Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"getAccountLiquidity(address)\":{\"notice\":\"Determine the current account liquidity wrt collateral requirements\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"notice\":\"Determine what the account liquidity would be if the given amounts were redeemed/borrowed\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"liquidateBorrowAllowed(address,address,address,address,uint256)\":{\"notice\":\"Checks if the liquidation should be allowed to occur\"},\"liquidateBorrowVerify(address,address,address,address,uint256,uint256)\":{\"notice\":\"Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"mintAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to mint tokens in the given market\"},\"mintVerify(address,address,uint256,uint256)\":{\"notice\":\"Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"redeemAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to redeem tokens in the given market\"},\"redeemVerify(address,address,uint256,uint256)\":{\"notice\":\"Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"repayBorrowAllowed(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to repay a borrow in the given market\"},\"repayBorrowVerify(address,address,address,uint256,uint256)\":{\"notice\":\"Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"seizeAllowed(address,address,address,address,uint256)\":{\"notice\":\"Checks if the seizing of assets should be allowed to occur\"},\"seizeVerify(address,address,address,address,uint256)\":{\"notice\":\"Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"transferAllowed(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to transfer tokens in the given market\"},\"transferVerify(address,address,address,uint256)\":{\"notice\":\"Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"}},\"notice\":\"This facet contract contains all the external pre-hook functions related to vToken\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/PolicyFacet.sol\":\"PolicyFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which corresponds to unlimited borrowing.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x13aa5a019c0ea5149d00480b5a3e1281ec316f8d159c52705f45b4c75a5abcb8\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/PolicyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IPolicyFacet } from \\\"../interfaces/IPolicyFacet.sol\\\";\\n\\nimport { XVSRewardsHelper } from \\\"./XVSRewardsHelper.sol\\\";\\n\\n/**\\n * @title PolicyFacet\\n * @author Venus\\n * @dev This facet contains all the hooks used while transferring the assets\\n * @notice This facet contract contains all the external pre-hook functions related to vToken\\n */\\ncontract PolicyFacet is IPolicyFacet, XVSRewardsHelper {\\n /// @notice Emitted when a new borrow-side XVS speed is calculated for a market\\n event VenusBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new supply-side XVS speed is calculated for a market\\n event VenusSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /**\\n * @notice Checks if the account should be allowed to mint tokens in the given market\\n * @param vToken The market to verify the mint against\\n * @param minter The account which would get the minted tokens\\n * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens\\n * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.MINT);\\n ensureListed(markets[vToken]);\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n require(supplyCap != 0, \\\"market supply cap is 0\\\");\\n\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n require(nextTotalSupply <= supplyCap, \\\"market supply cap reached\\\");\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, minter);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being minted\\n * @param minter The address minting the tokens\\n * @param actualMintAmount The amount of the underlying asset being minted\\n * @param mintTokens The number of tokens being minted\\n */\\n // solhint-disable-next-line no-unused-vars\\n function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(minter, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to redeem tokens in the given market\\n * @param vToken The market to verify the redeem against\\n * @param redeemer The account which would redeem the tokens\\n * @param redeemTokens The number of vTokens to exchange for the underlying asset in the market\\n * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256) {\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.REDEEM);\\n\\n uint256 allowed = redeemAllowedInternal(vToken, redeemer, redeemTokens);\\n if (allowed != uint256(Error.NO_ERROR)) {\\n return allowed;\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, redeemer);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being redeemed\\n * @param redeemer The address redeeming the tokens\\n * @param redeemAmount The amount of the underlying asset being redeemed\\n * @param redeemTokens The number of tokens being redeemed\\n */\\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {\\n require(redeemTokens != 0 || redeemAmount == 0, \\\"redeemTokens zero\\\");\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(redeemer, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to borrow the underlying asset of the given market\\n * @param vToken The market to verify the borrow against\\n * @param borrower The account which would borrow the asset\\n * @param borrowAmount The amount of underlying the account would borrow\\n * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.BORROW);\\n\\n ensureListed(markets[vToken]);\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n require(msg.sender == vToken, \\\"sender must be vToken\\\");\\n\\n // attempt to add borrower to the market\\n Error err = addToMarketInternal(VToken(vToken), borrower);\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n }\\n\\n if (oracle.getUnderlyingPrice(VToken(vToken)) == 0) {\\n return uint256(Error.PRICE_ERROR);\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Borrow cap of 0 corresponds to unlimited borrowing\\n if (borrowCap != 0) {\\n uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount);\\n require(nextTotalBorrows < borrowCap, \\\"market borrow cap reached\\\");\\n }\\n\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n\\n // Keep the flywheel moving\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n updateVenusBorrowIndex(vToken, borrowIndex);\\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset whose underlying is being borrowed\\n * @param borrower The address borrowing the underlying\\n * @param borrowAmount The amount of the underlying asset requested to borrow\\n */\\n // solhint-disable-next-line no-unused-vars\\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to repay a borrow in the given market\\n * @param vToken The market to verify the repay against\\n * @param payer The account which would repay the asset\\n * @param borrower The account which borrowed the asset\\n * @param repayAmount The amount of the underlying asset the account would repay\\n * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function repayBorrowAllowed(\\n address vToken,\\n address payer, // solhint-disable-line no-unused-vars\\n address borrower,\\n uint256 repayAmount // solhint-disable-line no-unused-vars\\n ) external returns (uint256) {\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.REPAY);\\n ensureListed(markets[vToken]);\\n\\n // Keep the flywheel moving\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n updateVenusBorrowIndex(vToken, borrowIndex);\\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being repaid\\n * @param payer The address repaying the borrow\\n * @param borrower The address of the borrower\\n * @param actualRepayAmount The amount of underlying being repaid\\n */\\n function repayBorrowVerify(\\n address vToken,\\n address payer, // solhint-disable-line no-unused-vars\\n address borrower,\\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n uint256 borrowerIndex // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the liquidation should be allowed to occur\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n */\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount\\n ) external view returns (uint256) {\\n checkProtocolPauseState();\\n\\n // if we want to pause liquidating to vTokenCollateral, we should pause seizing\\n checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n if (liquidatorContract != address(0) && liquidator != liquidatorContract) {\\n return uint256(Error.UNAUTHORIZED);\\n }\\n\\n ensureListed(markets[vTokenCollateral]);\\n\\n uint256 borrowBalance;\\n if (address(vTokenBorrowed) != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n } else {\\n borrowBalance = vaiController.getVAIRepayAmount(borrower);\\n }\\n\\n if (isForcedLiquidationEnabled[vTokenBorrowed] || isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed]) {\\n if (repayAmount > borrowBalance) {\\n return uint(Error.TOO_MUCH_REPAY);\\n }\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* The borrower must have shortfall in order to be liquidatable */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(borrower, VToken(address(0)), 0, 0);\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall == 0) {\\n return uint256(Error.INSUFFICIENT_SHORTFALL);\\n }\\n\\n // The liquidator may not repay more than what is allowed by the closeFactor\\n //-- maxClose = multipy of closeFactorMantissa and borrowBalance\\n if (repayAmount > mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance)) {\\n return uint256(Error.TOO_MUCH_REPAY);\\n }\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param actualRepayAmount The amount of underlying being repaid\\n * @param seizeTokens The amount of collateral token that will be seized\\n */\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral, // solhint-disable-line no-unused-vars\\n address liquidator,\\n address borrower,\\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vTokenBorrowed);\\n prime.accrueInterestAndUpdateScore(liquidator, vTokenBorrowed);\\n }\\n }\\n\\n /**\\n * @notice Checks if the seizing of assets should be allowed to occur\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param seizeTokens The number of collateral tokens to seize\\n */\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n // We've added VAIController as a borrowed token list check for seize\\n ensureListed(market);\\n\\n if (!market.accountMembership[borrower]) {\\n return uint256(Error.MARKET_NOT_COLLATERAL);\\n }\\n\\n if (address(vTokenBorrowed) != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n\\n if (VToken(vTokenCollateral).comptroller() != VToken(vTokenBorrowed).comptroller()) {\\n return uint256(Error.COMPTROLLER_MISMATCH);\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vTokenCollateral);\\n distributeSupplierVenus(vTokenCollateral, borrower);\\n distributeSupplierVenus(vTokenCollateral, liquidator);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param seizeTokens The number of collateral tokens to seize\\n */\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed, // solhint-disable-line no-unused-vars\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vTokenCollateral);\\n prime.accrueInterestAndUpdateScore(liquidator, vTokenCollateral);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to transfer tokens in the given market\\n * @param vToken The market to verify the transfer against\\n * @param src The account which sources the tokens\\n * @param dst The account which receives the tokens\\n * @param transferTokens The number of vTokens to transfer\\n * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function transferAllowed(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.TRANSFER);\\n\\n // Currently the only consideration is whether or not\\n // the src is allowed to redeem this many tokens\\n uint256 allowed = redeemAllowedInternal(vToken, src, transferTokens);\\n if (allowed != uint256(Error.NO_ERROR)) {\\n return allowed;\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, src);\\n distributeSupplierVenus(vToken, dst);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being transferred\\n * @param src The account which sources the tokens\\n * @param dst The account which receives the tokens\\n * @param transferTokens The number of vTokens to transfer\\n */\\n // solhint-disable-next-line no-unused-vars\\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(src, vToken);\\n prime.accrueInterestAndUpdateScore(dst, vToken);\\n }\\n }\\n\\n /**\\n * @notice Determine the current account liquidity wrt collateral requirements\\n * @return (possible error code (semi-opaque),\\n account liquidity in excess of collateral requirements,\\n * account shortfall below collateral requirements)\\n */\\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256) {\\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n account,\\n VToken(address(0)),\\n 0,\\n 0\\n );\\n\\n return (uint256(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @return (possible error code (semi-opaque),\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) external view returns (uint256, uint256, uint256) {\\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount\\n );\\n return (uint256(err), liquidity, shortfall);\\n }\\n\\n // setter functionality\\n /**\\n * @notice Set XVS speed for a single market\\n * @dev Allows the contract admin to set XVS speed for a market\\n * @param vTokens The market whose XVS speed to update\\n * @param supplySpeeds New XVS speed for supply\\n * @param borrowSpeeds New XVS speed for borrow\\n */\\n function _setVenusSpeeds(\\n VToken[] calldata vTokens,\\n uint256[] calldata supplySpeeds,\\n uint256[] calldata borrowSpeeds\\n ) external {\\n ensureAdmin();\\n\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n ensureNonzeroAddress(address(vTokens[i]));\\n setVenusSpeedInternal(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n function setVenusSpeedInternal(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal {\\n ensureListed(markets[address(vToken)]);\\n\\n if (venusSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. XVS accrued properly for the old speed, and\\n // 2. XVS accrued at the new speed starts after this block.\\n\\n updateVenusSupplyIndex(address(vToken));\\n // Update speed and emit event\\n venusSupplySpeeds[address(vToken)] = supplySpeed;\\n emit VenusSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (venusBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. XVS accrued properly for the old speed, and\\n // 2. XVS accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n updateVenusBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n venusBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit VenusBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe0fb54a32a16f86bd8fe652d699a37f4e8198dd09af0a6306abfc5079e7ba7d5\"},\"contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\n\\n/**\\n * @title XVSRewardsHelper\\n * @author Venus\\n * @dev This contract contains internal functions used in RewardFacet and PolicyFacet\\n * @notice This facet contract contains the shared functions used by the RewardFacet and PolicyFacet\\n */\\ncontract XVSRewardsHelper is FacetBase {\\n /// @notice Emitted when XVS is distributed to a borrower\\n event DistributedBorrowerVenus(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 venusDelta,\\n uint256 venusBorrowIndex\\n );\\n\\n /// @notice Emitted when XVS is distributed to a supplier\\n event DistributedSupplierVenus(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 venusDelta,\\n uint256 venusSupplyIndex\\n );\\n\\n /**\\n * @notice Accrue XVS to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n */\\n function updateVenusBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n VenusMarketState storage borrowState = venusBorrowState[vToken];\\n uint256 borrowSpeed = venusBorrowSpeeds[vToken];\\n uint32 blockNumber = getBlockNumberAsUint32();\\n uint256 deltaBlocks = sub_(blockNumber, borrowState.block);\\n if (deltaBlocks != 0 && borrowSpeed != 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedVenus = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount != 0 ? fraction(accruedVenus, borrowAmount) : Double({ mantissa: 0 });\\n borrowState.index = safe224(add_(Double({ mantissa: borrowState.index }), ratio).mantissa, \\\"224\\\");\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks != 0) {\\n borrowState.block = blockNumber;\\n }\\n }\\n\\n /**\\n * @notice Accrue XVS to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n */\\n function updateVenusSupplyIndex(address vToken) internal {\\n VenusMarketState storage supplyState = venusSupplyState[vToken];\\n uint256 supplySpeed = venusSupplySpeeds[vToken];\\n uint32 blockNumber = getBlockNumberAsUint32();\\n\\n uint256 deltaBlocks = sub_(blockNumber, supplyState.block);\\n if (deltaBlocks != 0 && supplySpeed != 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedVenus = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens != 0 ? fraction(accruedVenus, supplyTokens) : Double({ mantissa: 0 });\\n supplyState.index = safe224(add_(Double({ mantissa: supplyState.index }), ratio).mantissa, \\\"224\\\");\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks != 0) {\\n supplyState.block = blockNumber;\\n }\\n }\\n\\n /**\\n * @notice Calculate XVS accrued by a supplier and possibly transfer it to them\\n * @param vToken The market in which the supplier is interacting\\n * @param supplier The address of the supplier to distribute XVS to\\n */\\n function distributeSupplierVenus(address vToken, address supplier) internal {\\n if (address(vaiVaultAddress) != address(0)) {\\n releaseToVault();\\n }\\n uint256 supplyIndex = venusSupplyState[vToken].index;\\n uint256 supplierIndex = venusSupplierIndex[vToken][supplier];\\n // Update supplier's index to the current index since we are distributing accrued XVS\\n venusSupplierIndex[vToken][supplier] = supplyIndex;\\n if (supplierIndex == 0 && supplyIndex >= venusInitialIndex) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with XVS accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = venusInitialIndex;\\n }\\n // Calculate change in the cumulative sum of the XVS per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n // Multiply of supplierTokens and supplierDelta\\n uint256 supplierDelta = mul_(VToken(vToken).balanceOf(supplier), deltaIndex);\\n // Addition of supplierAccrued and supplierDelta\\n venusAccrued[supplier] = add_(venusAccrued[supplier], supplierDelta);\\n emit DistributedSupplierVenus(VToken(vToken), supplier, supplierDelta, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate XVS accrued by a borrower and possibly transfer it to them\\n * @dev Borrowers will not begin to accrue until after the first interaction with the protocol\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute XVS to\\n */\\n function distributeBorrowerVenus(address vToken, address borrower, Exp memory marketBorrowIndex) internal {\\n if (address(vaiVaultAddress) != address(0)) {\\n releaseToVault();\\n }\\n uint256 borrowIndex = venusBorrowState[vToken].index;\\n uint256 borrowerIndex = venusBorrowerIndex[vToken][borrower];\\n // Update borrowers's index to the current index since we are distributing accrued XVS\\n venusBorrowerIndex[vToken][borrower] = borrowIndex;\\n if (borrowerIndex == 0 && borrowIndex >= venusInitialIndex) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with XVS accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = venusInitialIndex;\\n }\\n // Calculate change in the cumulative sum of the XVS per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n uint256 borrowerDelta = mul_(div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex);\\n venusAccrued[borrower] = add_(venusAccrued[borrower], borrowerDelta);\\n emit DistributedBorrowerVenus(VToken(vToken), borrower, borrowerDelta, borrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0xf13ee35960223103dfc4a661771ae73998d4d4ff5b27f37bbaa52409bbc6103b\"},\"contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface IPolicyFacet {\\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256);\\n\\n function mintVerify(address vToken, address minter, uint256 mintAmount, uint256 mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256);\\n\\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256);\\n\\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external returns (uint256);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint256 repayAmount,\\n uint256 borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount\\n ) external view returns (uint256);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n uint256 seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external returns (uint256);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external;\\n\\n function transferAllowed(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external returns (uint256);\\n\\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external;\\n\\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);\\n\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) external view returns (uint256, uint256, uint256);\\n\\n function _setVenusSpeeds(\\n VToken[] calldata vTokens,\\n uint256[] calldata supplySpeeds,\\n uint256[] calldata borrowSpeeds\\n ) external;\\n}\\n\",\"keccak256\":\"0xbcbbf088aa79d3fcc6945cfbff35b1f2591a803efa6344da1cbf2575f14713be\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function getVAIAddress() public view returns (address);\\n\\n function getMintableVAI(address minter) public view returns (uint, uint);\\n\\n function mintVAI(address minter, uint mintVAIAmount) external returns (uint);\\n\\n function repayVAI(address repayer, uint repayVAIAmount) external returns (uint);\\n\\n function liquidateVAI(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint, uint);\\n\\n function _initializeVenusVAIState(uint blockNumber) external returns (uint);\\n\\n function updateVenusVAIMintIndex() external returns (uint);\\n\\n function calcDistributeVAIMinterVenus(address vaiMinter) external returns (uint, uint, uint, uint);\\n\\n function getVAIRepayAmount(address account) public view returns (uint);\\n}\\n\",\"keccak256\":\"0x17eb6edb1262c4effcad86f614ff20d00256278485054b11aa5cf011ff6f8a86\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0xc77c4dd91f93f778c5048fa0e68cc0cad2fd4a308add54f0172c507858ce06c8\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061364e806100206000396000f3fe608060405234801561001057600080fd5b50600436106103af5760003560e01c80637d172bd5116101f4578063c5b4db551161011a578063e37d4b79116100ad578063ead1a8a01161007c578063ead1a8a014610b88578063f445d70314610c96578063f851a44014610cc4578063fa6331d814610ccc576103af565b8063e37d4b7914610af5578063e85a296014610b1b578063e875544614610b4a578063eabe7d9114610b52576103af565b8063d3270f99116100e9578063d3270f9914610a83578063da3d454c14610a8b578063dce1544914610ac1578063dcfbc0c714610aed576103af565b8063c5b4db5514610a09578063c5f956af14610a2d578063c7ee005e14610a35578063d02f735114610a3d576103af565b80639bb27d6211610192578063bbb8864a11610161578063bbb8864a14610997578063bdcdc258146109bd578063bec04f72146109f9578063bf32442d14610a01576103af565b80639bb27d6214610931578063b2eafc3914610939578063b8324c7c14610941578063bb82aa5e1461098f576103af565b80638c1ac18a116101ce5780638c1ac18a146108b35780638e8f294b146108d95780639254f5e51461092157806394b2294b14610929576103af565b80637d172bd51461087d5780637dc0d1d0146108855780638a7dc1651461088d576103af565b806347ef3b3b116102d95780635c778605116102775780636a56947e116102465780636a56947e146107eb5780636d35bf9114610827578063719f701b1461086d5780637655138314610875576103af565b80635c778605146107235780635dd3fc9d146107595780635ec88c791461077f5780635fc7e71e146107a5576103af565b80634e79238f116102b35780634e79238f1461063a5780634ef4c3e11461069457806351dff989146106ca57806352d84d1e14610706576103af565b806347ef3b3b146105c05780634a5844321461060c5780634ada90af14610632576103af565b806324008a62116103515780634088c73e116103205780634088c73e1461054657806341a18d2c1461054e57806341c728b91461057c578063425fad58146105b8576103af565b806324008a62146104d457806324a3d6221461051057806326782247146105185780632bc7e29e14610520576103af565b80630db4b4e51161038d5780630db4b4e51461042257806310b983381461042a5780631ededc911461046c57806321af4569146104b0576103af565b806302c3bcbb146103b457806304ef9d58146103ec57806308e0225c146103f4575b600080fd5b6103da600480360360208110156103ca57600080fd5b50356001600160a01b0316610cd4565b60408051918252519081900360200190f35b6103da610ce6565b6103da6004803603604081101561040a57600080fd5b506001600160a01b0381358116916020013516610cec565b6103da610d09565b6104586004803603604081101561044057600080fd5b506001600160a01b0381358116916020013516610d0f565b604080519115158252519081900360200190f35b6104ae600480360360a081101561048257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135610d2f565b005b6104b8610db6565b604080516001600160a01b039092168252519081900360200190f35b6103da600480360360808110156104ea57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610dc5565b6104b8610e9a565b6104b8610ea9565b6103da6004803603602081101561053657600080fd5b50356001600160a01b0316610eb8565b610458610eca565b6103da6004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610ed3565b6104ae6004803603608081101561059257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610ef0565b610458610f76565b6104ae600480360360c08110156105d657600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135610f85565b6103da6004803603602081101561062257600080fd5b50356001600160a01b031661107b565b6103da61108d565b6106766004803603608081101561065057600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611093565b60408051938452602084019290925282820152519081900360600190f35b6103da600480360360608110156106aa57600080fd5b506001600160a01b038135811691602081013590911690604001356110c9565b6104ae600480360360808110156106e057600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112cf565b6104b86004803603602081101561071c57600080fd5b5035611320565b6104ae6004803603606081101561073957600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6103da6004803603602081101561076f57600080fd5b50356001600160a01b03166113cc565b6106766004803603602081101561079557600080fd5b50356001600160a01b03166113de565b6103da600480360360a08110156107bb57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611413565b6104ae6004803603608081101561080157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356116ae565b6104ae600480360360a081101561083d57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611783565b6103da611858565b61045861185e565b6104b861186c565b6104b861187b565b6103da600480360360208110156108a357600080fd5b50356001600160a01b031661188a565b610458600480360360208110156108c957600080fd5b50356001600160a01b031661189c565b6108ff600480360360208110156108ef57600080fd5b50356001600160a01b03166118b1565b6040805193151584526020840192909252151582820152519081900360600190f35b6104b86118d7565b6103da6118e6565b6104b86118ec565b6104b86118fb565b6109676004803603602081101561095757600080fd5b50356001600160a01b031661190a565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104b8611934565b6103da600480360360208110156109ad57600080fd5b50356001600160a01b0316611943565b6103da600480360360808110156109d357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611955565b6103da6119a3565b6104b86119a9565b610a116119b8565b604080516001600160e01b039092168252519081900360200190f35b6104b86119ca565b6104b86119d9565b6103da600480360360a0811015610a5357600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356119e8565b6104b8611b91565b6103da60048036036060811015610aa157600080fd5b506001600160a01b03813581169160208101359091169060400135611ba0565b6104b860048036036040811015610ad757600080fd5b506001600160a01b038135169060200135611ee4565b6104b8611f19565b61096760048036036020811015610b0b57600080fd5b50356001600160a01b0316611f28565b61045860048036036040811015610b3157600080fd5b5080356001600160a01b0316906020013560ff16611f52565b6103da611f94565b6103da60048036036060811015610b6857600080fd5b506001600160a01b03813581169160208101359091169060400135611f9a565b6104ae60048036036060811015610b9e57600080fd5b810190602081018135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460208302840111600160201b83111715610beb57600080fd5b919390929091602081019035600160201b811115610c0857600080fd5b820183602082011115610c1a57600080fd5b803590602001918460208302840111600160201b83111715610c3b57600080fd5b919390929091602081019035600160201b811115610c5857600080fd5b820183602082011115610c6a57600080fd5b803590602001918460208302840111600160201b83111715610c8b57600080fd5b509092509050611fe9565b61045860048036036040811015610cac57600080fd5b506001600160a01b03813581169160200135166120c2565b6104b86120e2565b6103da6120f1565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03868116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050505b5050505050565b601e546001600160a01b031681565b6000610dcf6120f7565b610dda85600361214c565b6001600160a01b0385166000908152600960205260409020610dfb9061219f565b610e036135dc565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4757600080fd5b505afa158015610e5b573d6000803e3d6000fd5b505050506040513d6020811015610e7157600080fd5b505190529050610e8186826121ec565b610e8c8685836123a2565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610f5757600080fd5b505af1158015610f6b573d6000803e3d6000fd5b505050505b50505050565b60185462010000900460ff1681565b6031546001600160a01b03161561107357603154604080516367994e8b60e11b81526001600160a01b03868116600483015289811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0389811660048301528b81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b15801561105a57600080fd5b505af115801561106e573d6000803e3d6000fd5b505050505b505050505050565b601f6020526000908152604090205481565b60065481565b6000806000806000806110a88a8a8a8a612542565b9250925092508260138111156110ba57fe5b9a919950975095505050505050565b60006110d36120f7565b6110de84600061214c565b6001600160a01b03841660009081526009602052604090206110ff9061219f565b6001600160a01b03841660009081526027602052604090205480611163576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420737570706c792063617020697320360541b604482015290519081900360640190fd5b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119e57600080fd5b505afa1580156111b2573d6000803e3d6000fd5b505050506040513d60208110156111c857600080fd5b505190506111d46135dc565b6040518060200160405280886001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561121857600080fd5b505afa15801561122c573d6000803e3d6000fd5b505050506040513d602081101561124257600080fd5b5051905290506000611255828488612601565b9050838111156112ac576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420737570706c7920636170207265616368656400000000000000604482015290519081900360640190fd5b6112b588612629565b6112bf88886127b5565b60009450505050505b9392505050565b801515806112db575081155b610ef0576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d818154811061132d57fe5b6000918252602090912001546001600160a01b0316905081565b6031546001600160a01b0316156113c757603154604080516367994e8b60e11b81526001600160a01b03858116600483015286811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156113ae57600080fd5b505af11580156113c2573d6000803e3d6000fd5b505050505b505050565b602b6020526000908152604090205481565b6000806000806000806113f5876000806000612542565b92509250925082601381111561140757fe5b97919650945092505050565b600061141d6120f7565b61142886600561214c565b6025546001600160a01b03161580159061145057506025546001600160a01b03858116911614155b1561145d575060016116a5565b6001600160a01b038516600090815260096020526040902061147e9061219f565b6015546000906001600160a01b03888116911614611540576001600160a01b03871660009081526009602052604090206114b79061219f565b866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b505190506115bc565b60155460408051633c617c9160e11b81526001600160a01b038781166004830152915191909216916378c2f922916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505190505b6001600160a01b0387166000908152602d602052604090205460ff168061160857506001600160a01b038085166000908152603260209081526040808320938b168352929052205460ff165b1561162757808311156116205760115b9150506116a5565b6000611618565b600080611638866000806000612542565b9193509091506000905082601381111561164e57fe5b146116695781601381111561165f57fe5b93505050506116a5565b8061167557600361165f565b61168f60405180602001604052806005548152508461297d565b85111561169d57601161165f565b600093505050505b95945050505050565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b15801561171557600080fd5b505af1158015611729573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0387811660048301528981166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610f5757600080fd5b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03858116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156117ea57600080fd5b505af11580156117fe573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0388811660048301528a81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610d9657600080fd5b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b60075481565b6025546001600160a01b031681565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b600061195f6120f7565b61196a85600661214c565b600061197786868561299c565b90508015611986579050610e92565b61198f86612629565b61199986866127b5565b610e8c86856127b5565b60175481565b6033546001600160a01b031690565b6a0c097ce7bc90715b34b9f160241b81565b6021546001600160a01b031681565b6031546001600160a01b031681565b60006119f26120f7565b6119fd86600461214c565b6001600160a01b0386166000908152600960205260409020611a1e8161219f565b6001600160a01b038416600090815260028201602052604090205460ff16611a47576013611618565b6015546001600160a01b03878116911614611a7d576001600160a01b0386166000908152600960205260409020611a7d9061219f565b856001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505160408051635fe3b56760e01b815290516001600160a01b03928316928a1691635fe3b567916004808301926020929190829003018186803b158015611b2657600080fd5b505afa158015611b3a573d6000803e3d6000fd5b505050506040513d6020811015611b5057600080fd5b50516001600160a01b031614611b67576002611618565b611b7087612629565b611b7a87856127b5565b611b8487866127b5565b6000979650505050505050565b6026546001600160a01b031681565b6000611baa6120f7565b611bb584600261214c565b6001600160a01b0384166000908152600960205260409020611bd69061219f565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16611c9357336001600160a01b03851614611c5c576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba103132903b2a37b5b2b760591b604482015290519081900360640190fd5b6000611c688585612a4e565b90506000816013811115611c7857fe5b14611c9157806013811115611c8957fe5b9150506112c8565b505b600480546040805163fc57d4df60e01b81526001600160a01b03888116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015611ce457600080fd5b505afa158015611cf8573d6000803e3d6000fd5b505050506040513d6020811015611d0e57600080fd5b5051611d1e57600d5b90506112c8565b6001600160a01b0384166000908152601f60205260409020548015611e05576000611dad866001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015611d7b57600080fd5b505afa158015611d8f573d6000803e3d6000fd5b505050506040513d6020811015611da557600080fd5b505185612b32565b9050818110611e03576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b505b600080611e158688600088612542565b91935090915060009050826013811115611e2b57fe5b14611e4657816013811115611e3c57fe5b93505050506112c8565b8015611e53576004611e3c565b611e5b6135dc565b6040518060200160405280896001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e9f57600080fd5b505afa158015611eb3573d6000803e3d6000fd5b505050506040513d6020811015611ec957600080fd5b505190529050611ed988826121ec565b6112bf8888836123a2565b60086020528160005260406000208181548110611efd57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b038216600090815260296020526040812081836008811115611f7757fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b6000611fa46120f7565b611faf84600161214c565b6000611fbc85858561299c565b90508015611fcb5790506112c8565b611fd485612629565b611fde85856127b5565b600095945050505050565b611ff1612b68565b84838114801561200057508082145b612041576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b81811015610f6b5761207088888381811061205b57fe5b905060200201356001600160a01b0316612bb8565b6120ba88888381811061207f57fe5b905060200201356001600160a01b031687878481811061209b57fe5b905060200201358686858181106120ae57fe5b90506020020135612c0b565b600101612044565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b60185462010000900460ff161561214a576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b565b6121568282611f52565b1561219b576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b5050565b805460ff166121e9576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b50565b6001600160a01b0382166000908152601160209081526040808320602a9092528220549091612219612da0565b835490915060009061223b9063ffffffff80851691600160e01b900416612de1565b9050801580159061224b57508215155b156123775760006122c0876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b15801561228e57600080fd5b505afa1580156122a2573d6000803e3d6000fd5b505050506040513d60208110156122b857600080fd5b505187612e1b565b905060006122ce8386612e39565b90506122d86135dc565b826122f257604051806020016040528060008152506122fc565b6122fc8284612e7b565b604080516020810190915288546001600160e01b03168152909150612345906123259083612eb8565b516040805180820190915260038152620c8c8d60ea1b6020820152612edd565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611073915050565b801561107357835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b601b546001600160a01b0316156123bb576123bb612f77565b6001600160a01b0383811660009081526011602090815260408083205460138352818420948716845293909152902080546001600160e01b0390921690819055908015801561241857506a0c097ce7bc90715b34b9f160241b8210155b1561242e57506a0c097ce7bc90715b34b9f160241b5b6124366135dc565b604051806020016040528061244b8585612de1565b815250905060006124b46124ae886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561228e57600080fd5b8361311f565b6001600160a01b0387166000908152601460205260409020549091506124da9082612b32565b6001600160a01b0380881660008181526014602090815260409182902094909455805185815293840188905280519193928b16927f837bdc11fca9f17ce44167944475225a205279b17e88c791c3b1f66f354668fb929081900390910190a350505050505050565b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b1580156125b557600080fd5b505afa1580156125c9573d6000803e3d6000fd5b505050506040513d60608110156125df57600080fd5b508051602082015160409092015190945090925090508260138111156110ba57fe5b600061260b6135dc565b612615858561314d565b90506116a56126238261316e565b84612b32565b6001600160a01b0381166000908152601060209081526040808320602b9092528220549091612656612da0565b83549091506000906126789063ffffffff80851691600160e01b900416612de1565b9050801580159061268857508215155b1561278b576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156126c857600080fd5b505afa1580156126dc573d6000803e3d6000fd5b505050506040513d60208110156126f257600080fd5b5051905060006127028386612e39565b905061270c6135dc565b826127265760405180602001604052806000815250612730565b6127308284612e7b565b604080516020810190915288546001600160e01b03168152909150612759906123259083612eb8565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550610daf915050565b8015610daf57835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b601b546001600160a01b0316156127ce576127ce612f77565b6001600160a01b0382811660009081526010602090815260408083205460128352818420948616845293909152902080546001600160e01b0390921690819055908015801561282b57506a0c097ce7bc90715b34b9f160241b8210155b1561284157506a0c097ce7bc90715b34b9f160241b5b6128496135dc565b604051806020016040528061285e8585612de1565b815250905060006128f0866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156128be57600080fd5b505afa1580156128d2573d6000803e3d6000fd5b505050506040513d60208110156128e857600080fd5b50518361311f565b6001600160a01b0386166000908152601460205260409020549091506129169082612b32565b6001600160a01b0380871660008181526014602090815260409182902094909455805185815293840188905280519193928a16927ffa9d964d891991c113b49e3db1932abd6c67263d387119707aafdd6c4010a3a9929081900390910190a3505050505050565b60006129876135dc565b612991848461314d565b9050610e928161316e565b6001600160a01b03831660009081526009602052604081206129bd9061219f565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166129f5576000611d17565b600080612a058587866000612542565b91935090915060009050826013811115612a1b57fe5b14612a3557816013811115612a2c57fe5b925050506112c8565b8015612a42576004612a2c565b60009695505050505050565b6000612a5b83600761214c565b6001600160a01b0383166000908152600960205260409020612a7c8161219f565b6001600160a01b038316600090815260028201602052604090205460ff1615612aa9576000915050611f8e565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b60006112c88383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b81525061317d565b6000546001600160a01b0316331461214a576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b6001600160a01b0381166121e9576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612c2c9061219f565b6001600160a01b0383166000908152602b60205260409020548214612ca557612c5483612629565b6001600160a01b0383166000818152602b6020908152604091829020859055815185815291517fa9ff26899e4982e7634afa9f70115dcfb61a17d6e8cdd91aa837671d0ff40ba69281900390910190a25b6001600160a01b0383166000908152602a602052604090205481146113c757612ccc6135dc565b6040518060200160405280856001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d1057600080fd5b505afa158015612d24573d6000803e3d6000fd5b505050506040513d6020811015612d3a57600080fd5b505190529050612d4a84826121ec565b6001600160a01b0384166000818152602a6020908152604091829020859055815185815291517f0c62c1bc89ec4c40dccb4d21543e782c5ba43897c0075d108d8964181ea3c51b9281900390910190a250505050565b6000612ddc612dad6131db565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b8152506131df565b905090565b60006112c88383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250613234565b60006112c8612e3284670de0b6b3a7640000612e39565b835161328e565b60006112c883836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f770000000000000000008152506132c1565b612e836135dc565b6040518060200160405280612eaf612ea9866a0c097ce7bc90715b34b9f160241b612e39565b8561328e565b90529392505050565b612ec06135dc565b6040518060200160405280612eaf85600001518560000151612b32565b600081600160e01b8410612f6f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612f34578181015183820152602001612f1c565b50505050905090810190601f168015612f615780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b601c541580612f8e5750601c54612f8c6131db565b105b15612f985761214a565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b158015612fe857600080fd5b505afa158015612ffc573d6000803e3d6000fd5b505050506040513d602081101561301257600080fd5b505190508061302257505061214a565b6000806130386130306131db565b601c54612de1565b90506000613048601a5483612e39565b90508084106130595780925061305d565b8392505b601d5483101561307157505050505061214a565b6130796131db565b601c55601b5461309c906001600160a01b0387811691168563ffffffff61333716565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d9657600080fd5b60006a0c097ce7bc90715b34b9f160241b61313e848460000151612e39565b8161314557fe5b049392505050565b6131556135dc565b6040518060200160405280612eaf856000015185612e39565b51670de0b6b3a7640000900490565b600083830182858210156131d25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b50949350505050565b4390565b600081600160201b8410612f6f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b600081848411156132865760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b505050900390565b60006112c883836040518060400160405280600e81526020016d646976696465206279207a65726f60901b815250613389565b60008315806132ce575082155b156132db575060006112c8565b838302838582816132e857fe5b041483906131d25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113c79084906133eb565b600081836133d85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b508284816133e257fe5b04949350505050565b6133fd826001600160a01b03166135a3565b61344e576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061348c5780518252601f19909201916020918201910161346d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146134ee576040519150601f19603f3d011682016040523d82523d6000602084013e6134f3565b606091505b50915091508161354a576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610f705780806020019051602081101561356657600080fd5b5051610f705760405162461bcd60e51b815260040180806020018281038252602a8152602001806135f0602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e92575050151592915050565b604051806020016040528060008152509056fe5361666542455032303a204245503230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820a677572e364f5bc86d0e0adaf762480e45c9fcb1112c6e95e877d0731a1c0ede64736f6c63430005100032", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103af5760003560e01c80637d172bd5116101f4578063c5b4db551161011a578063e37d4b79116100ad578063ead1a8a01161007c578063ead1a8a014610b88578063f445d70314610c96578063f851a44014610cc4578063fa6331d814610ccc576103af565b8063e37d4b7914610af5578063e85a296014610b1b578063e875544614610b4a578063eabe7d9114610b52576103af565b8063d3270f99116100e9578063d3270f9914610a83578063da3d454c14610a8b578063dce1544914610ac1578063dcfbc0c714610aed576103af565b8063c5b4db5514610a09578063c5f956af14610a2d578063c7ee005e14610a35578063d02f735114610a3d576103af565b80639bb27d6211610192578063bbb8864a11610161578063bbb8864a14610997578063bdcdc258146109bd578063bec04f72146109f9578063bf32442d14610a01576103af565b80639bb27d6214610931578063b2eafc3914610939578063b8324c7c14610941578063bb82aa5e1461098f576103af565b80638c1ac18a116101ce5780638c1ac18a146108b35780638e8f294b146108d95780639254f5e51461092157806394b2294b14610929576103af565b80637d172bd51461087d5780637dc0d1d0146108855780638a7dc1651461088d576103af565b806347ef3b3b116102d95780635c778605116102775780636a56947e116102465780636a56947e146107eb5780636d35bf9114610827578063719f701b1461086d5780637655138314610875576103af565b80635c778605146107235780635dd3fc9d146107595780635ec88c791461077f5780635fc7e71e146107a5576103af565b80634e79238f116102b35780634e79238f1461063a5780634ef4c3e11461069457806351dff989146106ca57806352d84d1e14610706576103af565b806347ef3b3b146105c05780634a5844321461060c5780634ada90af14610632576103af565b806324008a62116103515780634088c73e116103205780634088c73e1461054657806341a18d2c1461054e57806341c728b91461057c578063425fad58146105b8576103af565b806324008a62146104d457806324a3d6221461051057806326782247146105185780632bc7e29e14610520576103af565b80630db4b4e51161038d5780630db4b4e51461042257806310b983381461042a5780631ededc911461046c57806321af4569146104b0576103af565b806302c3bcbb146103b457806304ef9d58146103ec57806308e0225c146103f4575b600080fd5b6103da600480360360208110156103ca57600080fd5b50356001600160a01b0316610cd4565b60408051918252519081900360200190f35b6103da610ce6565b6103da6004803603604081101561040a57600080fd5b506001600160a01b0381358116916020013516610cec565b6103da610d09565b6104586004803603604081101561044057600080fd5b506001600160a01b0381358116916020013516610d0f565b604080519115158252519081900360200190f35b6104ae600480360360a081101561048257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135610d2f565b005b6104b8610db6565b604080516001600160a01b039092168252519081900360200190f35b6103da600480360360808110156104ea57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610dc5565b6104b8610e9a565b6104b8610ea9565b6103da6004803603602081101561053657600080fd5b50356001600160a01b0316610eb8565b610458610eca565b6103da6004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610ed3565b6104ae6004803603608081101561059257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610ef0565b610458610f76565b6104ae600480360360c08110156105d657600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135610f85565b6103da6004803603602081101561062257600080fd5b50356001600160a01b031661107b565b6103da61108d565b6106766004803603608081101561065057600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611093565b60408051938452602084019290925282820152519081900360600190f35b6103da600480360360608110156106aa57600080fd5b506001600160a01b038135811691602081013590911690604001356110c9565b6104ae600480360360808110156106e057600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112cf565b6104b86004803603602081101561071c57600080fd5b5035611320565b6104ae6004803603606081101561073957600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6103da6004803603602081101561076f57600080fd5b50356001600160a01b03166113cc565b6106766004803603602081101561079557600080fd5b50356001600160a01b03166113de565b6103da600480360360a08110156107bb57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611413565b6104ae6004803603608081101561080157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356116ae565b6104ae600480360360a081101561083d57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611783565b6103da611858565b61045861185e565b6104b861186c565b6104b861187b565b6103da600480360360208110156108a357600080fd5b50356001600160a01b031661188a565b610458600480360360208110156108c957600080fd5b50356001600160a01b031661189c565b6108ff600480360360208110156108ef57600080fd5b50356001600160a01b03166118b1565b6040805193151584526020840192909252151582820152519081900360600190f35b6104b86118d7565b6103da6118e6565b6104b86118ec565b6104b86118fb565b6109676004803603602081101561095757600080fd5b50356001600160a01b031661190a565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104b8611934565b6103da600480360360208110156109ad57600080fd5b50356001600160a01b0316611943565b6103da600480360360808110156109d357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611955565b6103da6119a3565b6104b86119a9565b610a116119b8565b604080516001600160e01b039092168252519081900360200190f35b6104b86119ca565b6104b86119d9565b6103da600480360360a0811015610a5357600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356119e8565b6104b8611b91565b6103da60048036036060811015610aa157600080fd5b506001600160a01b03813581169160208101359091169060400135611ba0565b6104b860048036036040811015610ad757600080fd5b506001600160a01b038135169060200135611ee4565b6104b8611f19565b61096760048036036020811015610b0b57600080fd5b50356001600160a01b0316611f28565b61045860048036036040811015610b3157600080fd5b5080356001600160a01b0316906020013560ff16611f52565b6103da611f94565b6103da60048036036060811015610b6857600080fd5b506001600160a01b03813581169160208101359091169060400135611f9a565b6104ae60048036036060811015610b9e57600080fd5b810190602081018135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460208302840111600160201b83111715610beb57600080fd5b919390929091602081019035600160201b811115610c0857600080fd5b820183602082011115610c1a57600080fd5b803590602001918460208302840111600160201b83111715610c3b57600080fd5b919390929091602081019035600160201b811115610c5857600080fd5b820183602082011115610c6a57600080fd5b803590602001918460208302840111600160201b83111715610c8b57600080fd5b509092509050611fe9565b61045860048036036040811015610cac57600080fd5b506001600160a01b03813581169160200135166120c2565b6104b86120e2565b6103da6120f1565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03868116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050505b5050505050565b601e546001600160a01b031681565b6000610dcf6120f7565b610dda85600361214c565b6001600160a01b0385166000908152600960205260409020610dfb9061219f565b610e036135dc565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4757600080fd5b505afa158015610e5b573d6000803e3d6000fd5b505050506040513d6020811015610e7157600080fd5b505190529050610e8186826121ec565b610e8c8685836123a2565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610f5757600080fd5b505af1158015610f6b573d6000803e3d6000fd5b505050505b50505050565b60185462010000900460ff1681565b6031546001600160a01b03161561107357603154604080516367994e8b60e11b81526001600160a01b03868116600483015289811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0389811660048301528b81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b15801561105a57600080fd5b505af115801561106e573d6000803e3d6000fd5b505050505b505050505050565b601f6020526000908152604090205481565b60065481565b6000806000806000806110a88a8a8a8a612542565b9250925092508260138111156110ba57fe5b9a919950975095505050505050565b60006110d36120f7565b6110de84600061214c565b6001600160a01b03841660009081526009602052604090206110ff9061219f565b6001600160a01b03841660009081526027602052604090205480611163576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420737570706c792063617020697320360541b604482015290519081900360640190fd5b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119e57600080fd5b505afa1580156111b2573d6000803e3d6000fd5b505050506040513d60208110156111c857600080fd5b505190506111d46135dc565b6040518060200160405280886001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561121857600080fd5b505afa15801561122c573d6000803e3d6000fd5b505050506040513d602081101561124257600080fd5b5051905290506000611255828488612601565b9050838111156112ac576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420737570706c7920636170207265616368656400000000000000604482015290519081900360640190fd5b6112b588612629565b6112bf88886127b5565b60009450505050505b9392505050565b801515806112db575081155b610ef0576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d818154811061132d57fe5b6000918252602090912001546001600160a01b0316905081565b6031546001600160a01b0316156113c757603154604080516367994e8b60e11b81526001600160a01b03858116600483015286811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156113ae57600080fd5b505af11580156113c2573d6000803e3d6000fd5b505050505b505050565b602b6020526000908152604090205481565b6000806000806000806113f5876000806000612542565b92509250925082601381111561140757fe5b97919650945092505050565b600061141d6120f7565b61142886600561214c565b6025546001600160a01b03161580159061145057506025546001600160a01b03858116911614155b1561145d575060016116a5565b6001600160a01b038516600090815260096020526040902061147e9061219f565b6015546000906001600160a01b03888116911614611540576001600160a01b03871660009081526009602052604090206114b79061219f565b866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b505190506115bc565b60155460408051633c617c9160e11b81526001600160a01b038781166004830152915191909216916378c2f922916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505190505b6001600160a01b0387166000908152602d602052604090205460ff168061160857506001600160a01b038085166000908152603260209081526040808320938b168352929052205460ff165b1561162757808311156116205760115b9150506116a5565b6000611618565b600080611638866000806000612542565b9193509091506000905082601381111561164e57fe5b146116695781601381111561165f57fe5b93505050506116a5565b8061167557600361165f565b61168f60405180602001604052806005548152508461297d565b85111561169d57601161165f565b600093505050505b95945050505050565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b15801561171557600080fd5b505af1158015611729573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0387811660048301528981166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610f5757600080fd5b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03858116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156117ea57600080fd5b505af11580156117fe573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0388811660048301528a81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610d9657600080fd5b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b60075481565b6025546001600160a01b031681565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b600061195f6120f7565b61196a85600661214c565b600061197786868561299c565b90508015611986579050610e92565b61198f86612629565b61199986866127b5565b610e8c86856127b5565b60175481565b6033546001600160a01b031690565b6a0c097ce7bc90715b34b9f160241b81565b6021546001600160a01b031681565b6031546001600160a01b031681565b60006119f26120f7565b6119fd86600461214c565b6001600160a01b0386166000908152600960205260409020611a1e8161219f565b6001600160a01b038416600090815260028201602052604090205460ff16611a47576013611618565b6015546001600160a01b03878116911614611a7d576001600160a01b0386166000908152600960205260409020611a7d9061219f565b856001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505160408051635fe3b56760e01b815290516001600160a01b03928316928a1691635fe3b567916004808301926020929190829003018186803b158015611b2657600080fd5b505afa158015611b3a573d6000803e3d6000fd5b505050506040513d6020811015611b5057600080fd5b50516001600160a01b031614611b67576002611618565b611b7087612629565b611b7a87856127b5565b611b8487866127b5565b6000979650505050505050565b6026546001600160a01b031681565b6000611baa6120f7565b611bb584600261214c565b6001600160a01b0384166000908152600960205260409020611bd69061219f565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16611c9357336001600160a01b03851614611c5c576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba103132903b2a37b5b2b760591b604482015290519081900360640190fd5b6000611c688585612a4e565b90506000816013811115611c7857fe5b14611c9157806013811115611c8957fe5b9150506112c8565b505b600480546040805163fc57d4df60e01b81526001600160a01b03888116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015611ce457600080fd5b505afa158015611cf8573d6000803e3d6000fd5b505050506040513d6020811015611d0e57600080fd5b5051611d1e57600d5b90506112c8565b6001600160a01b0384166000908152601f60205260409020548015611e05576000611dad866001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015611d7b57600080fd5b505afa158015611d8f573d6000803e3d6000fd5b505050506040513d6020811015611da557600080fd5b505185612b32565b9050818110611e03576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b505b600080611e158688600088612542565b91935090915060009050826013811115611e2b57fe5b14611e4657816013811115611e3c57fe5b93505050506112c8565b8015611e53576004611e3c565b611e5b6135dc565b6040518060200160405280896001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e9f57600080fd5b505afa158015611eb3573d6000803e3d6000fd5b505050506040513d6020811015611ec957600080fd5b505190529050611ed988826121ec565b6112bf8888836123a2565b60086020528160005260406000208181548110611efd57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b038216600090815260296020526040812081836008811115611f7757fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b6000611fa46120f7565b611faf84600161214c565b6000611fbc85858561299c565b90508015611fcb5790506112c8565b611fd485612629565b611fde85856127b5565b600095945050505050565b611ff1612b68565b84838114801561200057508082145b612041576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b81811015610f6b5761207088888381811061205b57fe5b905060200201356001600160a01b0316612bb8565b6120ba88888381811061207f57fe5b905060200201356001600160a01b031687878481811061209b57fe5b905060200201358686858181106120ae57fe5b90506020020135612c0b565b600101612044565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b60185462010000900460ff161561214a576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b565b6121568282611f52565b1561219b576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b5050565b805460ff166121e9576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b50565b6001600160a01b0382166000908152601160209081526040808320602a9092528220549091612219612da0565b835490915060009061223b9063ffffffff80851691600160e01b900416612de1565b9050801580159061224b57508215155b156123775760006122c0876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b15801561228e57600080fd5b505afa1580156122a2573d6000803e3d6000fd5b505050506040513d60208110156122b857600080fd5b505187612e1b565b905060006122ce8386612e39565b90506122d86135dc565b826122f257604051806020016040528060008152506122fc565b6122fc8284612e7b565b604080516020810190915288546001600160e01b03168152909150612345906123259083612eb8565b516040805180820190915260038152620c8c8d60ea1b6020820152612edd565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611073915050565b801561107357835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b601b546001600160a01b0316156123bb576123bb612f77565b6001600160a01b0383811660009081526011602090815260408083205460138352818420948716845293909152902080546001600160e01b0390921690819055908015801561241857506a0c097ce7bc90715b34b9f160241b8210155b1561242e57506a0c097ce7bc90715b34b9f160241b5b6124366135dc565b604051806020016040528061244b8585612de1565b815250905060006124b46124ae886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561228e57600080fd5b8361311f565b6001600160a01b0387166000908152601460205260409020549091506124da9082612b32565b6001600160a01b0380881660008181526014602090815260409182902094909455805185815293840188905280519193928b16927f837bdc11fca9f17ce44167944475225a205279b17e88c791c3b1f66f354668fb929081900390910190a350505050505050565b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b1580156125b557600080fd5b505afa1580156125c9573d6000803e3d6000fd5b505050506040513d60608110156125df57600080fd5b508051602082015160409092015190945090925090508260138111156110ba57fe5b600061260b6135dc565b612615858561314d565b90506116a56126238261316e565b84612b32565b6001600160a01b0381166000908152601060209081526040808320602b9092528220549091612656612da0565b83549091506000906126789063ffffffff80851691600160e01b900416612de1565b9050801580159061268857508215155b1561278b576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156126c857600080fd5b505afa1580156126dc573d6000803e3d6000fd5b505050506040513d60208110156126f257600080fd5b5051905060006127028386612e39565b905061270c6135dc565b826127265760405180602001604052806000815250612730565b6127308284612e7b565b604080516020810190915288546001600160e01b03168152909150612759906123259083612eb8565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550610daf915050565b8015610daf57835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b601b546001600160a01b0316156127ce576127ce612f77565b6001600160a01b0382811660009081526010602090815260408083205460128352818420948616845293909152902080546001600160e01b0390921690819055908015801561282b57506a0c097ce7bc90715b34b9f160241b8210155b1561284157506a0c097ce7bc90715b34b9f160241b5b6128496135dc565b604051806020016040528061285e8585612de1565b815250905060006128f0866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156128be57600080fd5b505afa1580156128d2573d6000803e3d6000fd5b505050506040513d60208110156128e857600080fd5b50518361311f565b6001600160a01b0386166000908152601460205260409020549091506129169082612b32565b6001600160a01b0380871660008181526014602090815260409182902094909455805185815293840188905280519193928a16927ffa9d964d891991c113b49e3db1932abd6c67263d387119707aafdd6c4010a3a9929081900390910190a3505050505050565b60006129876135dc565b612991848461314d565b9050610e928161316e565b6001600160a01b03831660009081526009602052604081206129bd9061219f565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166129f5576000611d17565b600080612a058587866000612542565b91935090915060009050826013811115612a1b57fe5b14612a3557816013811115612a2c57fe5b925050506112c8565b8015612a42576004612a2c565b60009695505050505050565b6000612a5b83600761214c565b6001600160a01b0383166000908152600960205260409020612a7c8161219f565b6001600160a01b038316600090815260028201602052604090205460ff1615612aa9576000915050611f8e565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b60006112c88383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b81525061317d565b6000546001600160a01b0316331461214a576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b6001600160a01b0381166121e9576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612c2c9061219f565b6001600160a01b0383166000908152602b60205260409020548214612ca557612c5483612629565b6001600160a01b0383166000818152602b6020908152604091829020859055815185815291517fa9ff26899e4982e7634afa9f70115dcfb61a17d6e8cdd91aa837671d0ff40ba69281900390910190a25b6001600160a01b0383166000908152602a602052604090205481146113c757612ccc6135dc565b6040518060200160405280856001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d1057600080fd5b505afa158015612d24573d6000803e3d6000fd5b505050506040513d6020811015612d3a57600080fd5b505190529050612d4a84826121ec565b6001600160a01b0384166000818152602a6020908152604091829020859055815185815291517f0c62c1bc89ec4c40dccb4d21543e782c5ba43897c0075d108d8964181ea3c51b9281900390910190a250505050565b6000612ddc612dad6131db565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b8152506131df565b905090565b60006112c88383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250613234565b60006112c8612e3284670de0b6b3a7640000612e39565b835161328e565b60006112c883836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f770000000000000000008152506132c1565b612e836135dc565b6040518060200160405280612eaf612ea9866a0c097ce7bc90715b34b9f160241b612e39565b8561328e565b90529392505050565b612ec06135dc565b6040518060200160405280612eaf85600001518560000151612b32565b600081600160e01b8410612f6f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612f34578181015183820152602001612f1c565b50505050905090810190601f168015612f615780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b601c541580612f8e5750601c54612f8c6131db565b105b15612f985761214a565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b158015612fe857600080fd5b505afa158015612ffc573d6000803e3d6000fd5b505050506040513d602081101561301257600080fd5b505190508061302257505061214a565b6000806130386130306131db565b601c54612de1565b90506000613048601a5483612e39565b90508084106130595780925061305d565b8392505b601d5483101561307157505050505061214a565b6130796131db565b601c55601b5461309c906001600160a01b0387811691168563ffffffff61333716565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d9657600080fd5b60006a0c097ce7bc90715b34b9f160241b61313e848460000151612e39565b8161314557fe5b049392505050565b6131556135dc565b6040518060200160405280612eaf856000015185612e39565b51670de0b6b3a7640000900490565b600083830182858210156131d25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b50949350505050565b4390565b600081600160201b8410612f6f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b600081848411156132865760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b505050900390565b60006112c883836040518060400160405280600e81526020016d646976696465206279207a65726f60901b815250613389565b60008315806132ce575082155b156132db575060006112c8565b838302838582816132e857fe5b041483906131d25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113c79084906133eb565b600081836133d85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b508284816133e257fe5b04949350505050565b6133fd826001600160a01b03166135a3565b61344e576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061348c5780518252601f19909201916020918201910161346d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146134ee576040519150601f19603f3d011682016040523d82523d6000602084013e6134f3565b606091505b50915091508161354a576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610f705780806020019051602081101561356657600080fd5b5051610f705760405162461bcd60e51b815260040180806020018281038252602a8152602001806135f0602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e92575050151592915050565b604051806020016040528060008152509056fe5361666542455032303a204245503230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820a677572e364f5bc86d0e0adaf762480e45c9fcb1112c6e95e877d0731a1c0ede64736f6c63430005100032", + "numDeployments": 3, + "solcInputHash": "ce1a4122e5f4f14eccfd5d8b352422cb", + "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusDelta\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusBorrowIndex\",\"type\":\"uint256\"}],\"name\":\"DistributedBorrowerVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"supplier\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusDelta\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusSupplyIndex\",\"type\":\"uint256\"}],\"name\":\"DistributedSupplierVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"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\":false,\"internalType\":\"uint256\",\"name\":\"newSpeed\",\"type\":\"uint256\"}],\"name\":\"VenusBorrowSpeedUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSpeed\",\"type\":\"uint256\"}],\"name\":\"VenusSupplySpeedUpdated\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"supplySpeeds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"borrowSpeeds\",\"type\":\"uint256[]\"}],\"name\":\"_setVenusSpeeds\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"borrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"borrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenModify\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"getHypotheticalAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateBorrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"liquidateBorrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"mintAmount\",\"type\":\"uint256\"}],\"name\":\"mintAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualMintAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mintTokens\",\"type\":\"uint256\"}],\"name\":\"mintVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"redeemAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"redeemVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"name\":\"repayBorrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowerIndex\",\"type\":\"uint256\"}],\"name\":\"repayBorrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"seizeAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"seizeVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"transferAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"transferVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the hooks used while transferring the assets\",\"methods\":{\"_setVenusSpeeds(address[],uint256[],uint256[])\":{\"details\":\"Allows the contract admin to set XVS speed for a market\",\"params\":{\"borrowSpeeds\":\"New XVS speed for borrow\",\"supplySpeeds\":\"New XVS speed for supply\",\"vTokens\":\"The market whose XVS speed to update\"}},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"borrowAllowed(address,address,uint256)\":{\"params\":{\"borrowAmount\":\"The amount of underlying the account would borrow\",\"borrower\":\"The account which would borrow the asset\",\"vToken\":\"The market to verify the borrow against\"},\"return\":\"0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"borrowVerify(address,address,uint256)\":{\"params\":{\"borrowAmount\":\"The amount of the underlying asset requested to borrow\",\"borrower\":\"The address borrowing the underlying\",\"vToken\":\"Asset whose underlying is being borrowed\"}},\"getAccountLiquidity(address)\":{\"return\":\"(possible error code (semi-opaque), account liquidity in excess of collateral requirements, account shortfall below collateral requirements)\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"params\":{\"account\":\"The account to determine liquidity for\",\"borrowAmount\":\"The amount of underlying to hypothetically borrow\",\"redeemTokens\":\"The number of tokens to hypothetically redeem\",\"vTokenModify\":\"The market to hypothetically redeem/borrow in\"},\"return\":\"(possible error code (semi-opaque), hypothetical account liquidity in excess of collateral requirements, hypothetical account shortfall below collateral requirements)\"},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"liquidateBorrowAllowed(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"repayAmount\":\"The amount of underlying being repaid\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"liquidateBorrowVerify(address,address,address,address,uint256,uint256)\":{\"params\":{\"actualRepayAmount\":\"The amount of underlying being repaid\",\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The amount of collateral token that will be seized\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"mintAllowed(address,address,uint256)\":{\"params\":{\"mintAmount\":\"The amount of underlying being supplied to the market in exchange for tokens\",\"minter\":\"The account which would get the minted tokens\",\"vToken\":\"The market to verify the mint against\"},\"return\":\"0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"mintVerify(address,address,uint256,uint256)\":{\"params\":{\"actualMintAmount\":\"The amount of the underlying asset being minted\",\"mintTokens\":\"The number of tokens being minted\",\"minter\":\"The address minting the tokens\",\"vToken\":\"Asset being minted\"}},\"redeemAllowed(address,address,uint256)\":{\"params\":{\"redeemTokens\":\"The number of vTokens to exchange for the underlying asset in the market\",\"redeemer\":\"The account which would redeem the tokens\",\"vToken\":\"The market to verify the redeem against\"},\"return\":\"0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"redeemVerify(address,address,uint256,uint256)\":{\"params\":{\"redeemAmount\":\"The amount of the underlying asset being redeemed\",\"redeemTokens\":\"The number of tokens being redeemed\",\"redeemer\":\"The address redeeming the tokens\",\"vToken\":\"Asset being redeemed\"}},\"repayBorrowAllowed(address,address,address,uint256)\":{\"params\":{\"borrower\":\"The account which borrowed the asset\",\"payer\":\"The account which would repay the asset\",\"repayAmount\":\"The amount of the underlying asset the account would repay\",\"vToken\":\"The market to verify the repay against\"},\"return\":\"0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"repayBorrowVerify(address,address,address,uint256,uint256)\":{\"params\":{\"actualRepayAmount\":\"The amount of underlying being repaid\",\"borrower\":\"The address of the borrower\",\"payer\":\"The address repaying the borrow\",\"vToken\":\"Asset being repaid\"}},\"seizeAllowed(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The number of collateral tokens to seize\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"seizeVerify(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The number of collateral tokens to seize\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"transferAllowed(address,address,address,uint256)\":{\"params\":{\"dst\":\"The account which receives the tokens\",\"src\":\"The account which sources the tokens\",\"transferTokens\":\"The number of vTokens to transfer\",\"vToken\":\"The market to verify the transfer against\"},\"return\":\"0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"transferVerify(address,address,address,uint256)\":{\"params\":{\"dst\":\"The account which receives the tokens\",\"src\":\"The account which sources the tokens\",\"transferTokens\":\"The number of vTokens to transfer\",\"vToken\":\"Asset being transferred\"}}},\"title\":\"PolicyFacet\"},\"userdoc\":{\"methods\":{\"_setVenusSpeeds(address[],uint256[],uint256[])\":{\"notice\":\"Set XVS speed for a single market\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"borrowAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to borrow the underlying asset of the given market\"},\"borrowVerify(address,address,uint256)\":{\"notice\":\"Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"getAccountLiquidity(address)\":{\"notice\":\"Determine the current account liquidity wrt collateral requirements\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"notice\":\"Determine what the account liquidity would be if the given amounts were redeemed/borrowed\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"liquidateBorrowAllowed(address,address,address,address,uint256)\":{\"notice\":\"Checks if the liquidation should be allowed to occur\"},\"liquidateBorrowVerify(address,address,address,address,uint256,uint256)\":{\"notice\":\"Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"mintAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to mint tokens in the given market\"},\"mintVerify(address,address,uint256,uint256)\":{\"notice\":\"Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"redeemAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to redeem tokens in the given market\"},\"redeemVerify(address,address,uint256,uint256)\":{\"notice\":\"Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"repayBorrowAllowed(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to repay a borrow in the given market\"},\"repayBorrowVerify(address,address,address,uint256,uint256)\":{\"notice\":\"Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"seizeAllowed(address,address,address,address,uint256)\":{\"notice\":\"Checks if the seizing of assets should be allowed to occur\"},\"seizeVerify(address,address,address,address,uint256)\":{\"notice\":\"Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"transferAllowed(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to transfer tokens in the given market\"},\"transferVerify(address,address,address,uint256)\":{\"notice\":\"Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"}},\"notice\":\"This facet contract contains all the external pre-hook functions related to vToken\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/PolicyFacet.sol\":\"PolicyFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x06608bb502e91c33fda8c0dd88cc79a49a078fab521bc27d10fc3a69c1da55f4\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/PolicyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IPolicyFacet } from \\\"../interfaces/IPolicyFacet.sol\\\";\\n\\nimport { XVSRewardsHelper } from \\\"./XVSRewardsHelper.sol\\\";\\n\\n/**\\n * @title PolicyFacet\\n * @author Venus\\n * @dev This facet contains all the hooks used while transferring the assets\\n * @notice This facet contract contains all the external pre-hook functions related to vToken\\n */\\ncontract PolicyFacet is IPolicyFacet, XVSRewardsHelper {\\n /// @notice Emitted when a new borrow-side XVS speed is calculated for a market\\n event VenusBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new supply-side XVS speed is calculated for a market\\n event VenusSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /**\\n * @notice Checks if the account should be allowed to mint tokens in the given market\\n * @param vToken The market to verify the mint against\\n * @param minter The account which would get the minted tokens\\n * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens\\n * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.MINT);\\n ensureListed(markets[vToken]);\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n require(supplyCap != 0, \\\"market supply cap is 0\\\");\\n\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n require(nextTotalSupply <= supplyCap, \\\"market supply cap reached\\\");\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, minter);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being minted\\n * @param minter The address minting the tokens\\n * @param actualMintAmount The amount of the underlying asset being minted\\n * @param mintTokens The number of tokens being minted\\n */\\n // solhint-disable-next-line no-unused-vars\\n function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(minter, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to redeem tokens in the given market\\n * @param vToken The market to verify the redeem against\\n * @param redeemer The account which would redeem the tokens\\n * @param redeemTokens The number of vTokens to exchange for the underlying asset in the market\\n * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256) {\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.REDEEM);\\n\\n uint256 allowed = redeemAllowedInternal(vToken, redeemer, redeemTokens);\\n if (allowed != uint256(Error.NO_ERROR)) {\\n return allowed;\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, redeemer);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being redeemed\\n * @param redeemer The address redeeming the tokens\\n * @param redeemAmount The amount of the underlying asset being redeemed\\n * @param redeemTokens The number of tokens being redeemed\\n */\\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {\\n require(redeemTokens != 0 || redeemAmount == 0, \\\"redeemTokens zero\\\");\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(redeemer, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to borrow the underlying asset of the given market\\n * @param vToken The market to verify the borrow against\\n * @param borrower The account which would borrow the asset\\n * @param borrowAmount The amount of underlying the account would borrow\\n * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.BORROW);\\n ensureListed(markets[vToken]);\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n require(borrowCap != 0, \\\"market borrow cap is 0\\\");\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n require(msg.sender == vToken, \\\"sender must be vToken\\\");\\n\\n // attempt to add borrower to the market\\n Error err = addToMarketInternal(VToken(vToken), borrower);\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n }\\n\\n if (oracle.getUnderlyingPrice(VToken(vToken)) == 0) {\\n return uint256(Error.PRICE_ERROR);\\n }\\n\\n uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount);\\n require(nextTotalBorrows <= borrowCap, \\\"market borrow cap reached\\\");\\n\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n\\n // Keep the flywheel moving\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n updateVenusBorrowIndex(vToken, borrowIndex);\\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset whose underlying is being borrowed\\n * @param borrower The address borrowing the underlying\\n * @param borrowAmount The amount of the underlying asset requested to borrow\\n */\\n // solhint-disable-next-line no-unused-vars\\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to repay a borrow in the given market\\n * @param vToken The market to verify the repay against\\n * @param payer The account which would repay the asset\\n * @param borrower The account which borrowed the asset\\n * @param repayAmount The amount of the underlying asset the account would repay\\n * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function repayBorrowAllowed(\\n address vToken,\\n address payer, // solhint-disable-line no-unused-vars\\n address borrower,\\n uint256 repayAmount // solhint-disable-line no-unused-vars\\n ) external returns (uint256) {\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.REPAY);\\n ensureListed(markets[vToken]);\\n\\n // Keep the flywheel moving\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n updateVenusBorrowIndex(vToken, borrowIndex);\\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being repaid\\n * @param payer The address repaying the borrow\\n * @param borrower The address of the borrower\\n * @param actualRepayAmount The amount of underlying being repaid\\n */\\n function repayBorrowVerify(\\n address vToken,\\n address payer, // solhint-disable-line no-unused-vars\\n address borrower,\\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n uint256 borrowerIndex // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the liquidation should be allowed to occur\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n */\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount\\n ) external view returns (uint256) {\\n checkProtocolPauseState();\\n\\n // if we want to pause liquidating to vTokenCollateral, we should pause seizing\\n checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n if (liquidatorContract != address(0) && liquidator != liquidatorContract) {\\n return uint256(Error.UNAUTHORIZED);\\n }\\n\\n ensureListed(markets[vTokenCollateral]);\\n\\n uint256 borrowBalance;\\n if (address(vTokenBorrowed) != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n } else {\\n borrowBalance = vaiController.getVAIRepayAmount(borrower);\\n }\\n\\n if (isForcedLiquidationEnabled[vTokenBorrowed] || isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed]) {\\n if (repayAmount > borrowBalance) {\\n return uint(Error.TOO_MUCH_REPAY);\\n }\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* The borrower must have shortfall in order to be liquidatable */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(borrower, VToken(address(0)), 0, 0);\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall == 0) {\\n return uint256(Error.INSUFFICIENT_SHORTFALL);\\n }\\n\\n // The liquidator may not repay more than what is allowed by the closeFactor\\n //-- maxClose = multipy of closeFactorMantissa and borrowBalance\\n if (repayAmount > mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance)) {\\n return uint256(Error.TOO_MUCH_REPAY);\\n }\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param actualRepayAmount The amount of underlying being repaid\\n * @param seizeTokens The amount of collateral token that will be seized\\n */\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral, // solhint-disable-line no-unused-vars\\n address liquidator,\\n address borrower,\\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vTokenBorrowed);\\n prime.accrueInterestAndUpdateScore(liquidator, vTokenBorrowed);\\n }\\n }\\n\\n /**\\n * @notice Checks if the seizing of assets should be allowed to occur\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param seizeTokens The number of collateral tokens to seize\\n */\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n // We've added VAIController as a borrowed token list check for seize\\n ensureListed(market);\\n\\n if (!market.accountMembership[borrower]) {\\n return uint256(Error.MARKET_NOT_COLLATERAL);\\n }\\n\\n if (address(vTokenBorrowed) != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n\\n if (VToken(vTokenCollateral).comptroller() != VToken(vTokenBorrowed).comptroller()) {\\n return uint256(Error.COMPTROLLER_MISMATCH);\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vTokenCollateral);\\n distributeSupplierVenus(vTokenCollateral, borrower);\\n distributeSupplierVenus(vTokenCollateral, liquidator);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param seizeTokens The number of collateral tokens to seize\\n */\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed, // solhint-disable-line no-unused-vars\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vTokenCollateral);\\n prime.accrueInterestAndUpdateScore(liquidator, vTokenCollateral);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to transfer tokens in the given market\\n * @param vToken The market to verify the transfer against\\n * @param src The account which sources the tokens\\n * @param dst The account which receives the tokens\\n * @param transferTokens The number of vTokens to transfer\\n * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function transferAllowed(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.TRANSFER);\\n\\n // Currently the only consideration is whether or not\\n // the src is allowed to redeem this many tokens\\n uint256 allowed = redeemAllowedInternal(vToken, src, transferTokens);\\n if (allowed != uint256(Error.NO_ERROR)) {\\n return allowed;\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, src);\\n distributeSupplierVenus(vToken, dst);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being transferred\\n * @param src The account which sources the tokens\\n * @param dst The account which receives the tokens\\n * @param transferTokens The number of vTokens to transfer\\n */\\n // solhint-disable-next-line no-unused-vars\\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(src, vToken);\\n prime.accrueInterestAndUpdateScore(dst, vToken);\\n }\\n }\\n\\n /**\\n * @notice Determine the current account liquidity wrt collateral requirements\\n * @return (possible error code (semi-opaque),\\n account liquidity in excess of collateral requirements,\\n * account shortfall below collateral requirements)\\n */\\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256) {\\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n account,\\n VToken(address(0)),\\n 0,\\n 0\\n );\\n\\n return (uint256(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @return (possible error code (semi-opaque),\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) external view returns (uint256, uint256, uint256) {\\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount\\n );\\n return (uint256(err), liquidity, shortfall);\\n }\\n\\n // setter functionality\\n /**\\n * @notice Set XVS speed for a single market\\n * @dev Allows the contract admin to set XVS speed for a market\\n * @param vTokens The market whose XVS speed to update\\n * @param supplySpeeds New XVS speed for supply\\n * @param borrowSpeeds New XVS speed for borrow\\n */\\n function _setVenusSpeeds(\\n VToken[] calldata vTokens,\\n uint256[] calldata supplySpeeds,\\n uint256[] calldata borrowSpeeds\\n ) external {\\n ensureAdmin();\\n\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n ensureNonzeroAddress(address(vTokens[i]));\\n setVenusSpeedInternal(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n function setVenusSpeedInternal(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal {\\n ensureListed(markets[address(vToken)]);\\n\\n if (venusSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. XVS accrued properly for the old speed, and\\n // 2. XVS accrued at the new speed starts after this block.\\n\\n updateVenusSupplyIndex(address(vToken));\\n // Update speed and emit event\\n venusSupplySpeeds[address(vToken)] = supplySpeed;\\n emit VenusSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (venusBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. XVS accrued properly for the old speed, and\\n // 2. XVS accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n updateVenusBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n venusBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit VenusBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x19e28f481bd47db3871b1ae379608c22c59b7d331b471eab7c972068403588e3\"},\"contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\n\\n/**\\n * @title XVSRewardsHelper\\n * @author Venus\\n * @dev This contract contains internal functions used in RewardFacet and PolicyFacet\\n * @notice This facet contract contains the shared functions used by the RewardFacet and PolicyFacet\\n */\\ncontract XVSRewardsHelper is FacetBase {\\n /// @notice Emitted when XVS is distributed to a borrower\\n event DistributedBorrowerVenus(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 venusDelta,\\n uint256 venusBorrowIndex\\n );\\n\\n /// @notice Emitted when XVS is distributed to a supplier\\n event DistributedSupplierVenus(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 venusDelta,\\n uint256 venusSupplyIndex\\n );\\n\\n /**\\n * @notice Accrue XVS to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n */\\n function updateVenusBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n VenusMarketState storage borrowState = venusBorrowState[vToken];\\n uint256 borrowSpeed = venusBorrowSpeeds[vToken];\\n uint32 blockNumber = getBlockNumberAsUint32();\\n uint256 deltaBlocks = sub_(blockNumber, borrowState.block);\\n if (deltaBlocks != 0 && borrowSpeed != 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedVenus = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount != 0 ? fraction(accruedVenus, borrowAmount) : Double({ mantissa: 0 });\\n borrowState.index = safe224(add_(Double({ mantissa: borrowState.index }), ratio).mantissa, \\\"224\\\");\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks != 0) {\\n borrowState.block = blockNumber;\\n }\\n }\\n\\n /**\\n * @notice Accrue XVS to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n */\\n function updateVenusSupplyIndex(address vToken) internal {\\n VenusMarketState storage supplyState = venusSupplyState[vToken];\\n uint256 supplySpeed = venusSupplySpeeds[vToken];\\n uint32 blockNumber = getBlockNumberAsUint32();\\n\\n uint256 deltaBlocks = sub_(blockNumber, supplyState.block);\\n if (deltaBlocks != 0 && supplySpeed != 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedVenus = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens != 0 ? fraction(accruedVenus, supplyTokens) : Double({ mantissa: 0 });\\n supplyState.index = safe224(add_(Double({ mantissa: supplyState.index }), ratio).mantissa, \\\"224\\\");\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks != 0) {\\n supplyState.block = blockNumber;\\n }\\n }\\n\\n /**\\n * @notice Calculate XVS accrued by a supplier and possibly transfer it to them\\n * @param vToken The market in which the supplier is interacting\\n * @param supplier The address of the supplier to distribute XVS to\\n */\\n function distributeSupplierVenus(address vToken, address supplier) internal {\\n if (address(vaiVaultAddress) != address(0)) {\\n releaseToVault();\\n }\\n uint256 supplyIndex = venusSupplyState[vToken].index;\\n uint256 supplierIndex = venusSupplierIndex[vToken][supplier];\\n // Update supplier's index to the current index since we are distributing accrued XVS\\n venusSupplierIndex[vToken][supplier] = supplyIndex;\\n if (supplierIndex == 0 && supplyIndex >= venusInitialIndex) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with XVS accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = venusInitialIndex;\\n }\\n // Calculate change in the cumulative sum of the XVS per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n // Multiply of supplierTokens and supplierDelta\\n uint256 supplierDelta = mul_(VToken(vToken).balanceOf(supplier), deltaIndex);\\n // Addition of supplierAccrued and supplierDelta\\n venusAccrued[supplier] = add_(venusAccrued[supplier], supplierDelta);\\n emit DistributedSupplierVenus(VToken(vToken), supplier, supplierDelta, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate XVS accrued by a borrower and possibly transfer it to them\\n * @dev Borrowers will not begin to accrue until after the first interaction with the protocol\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute XVS to\\n */\\n function distributeBorrowerVenus(address vToken, address borrower, Exp memory marketBorrowIndex) internal {\\n if (address(vaiVaultAddress) != address(0)) {\\n releaseToVault();\\n }\\n uint256 borrowIndex = venusBorrowState[vToken].index;\\n uint256 borrowerIndex = venusBorrowerIndex[vToken][borrower];\\n // Update borrowers's index to the current index since we are distributing accrued XVS\\n venusBorrowerIndex[vToken][borrower] = borrowIndex;\\n if (borrowerIndex == 0 && borrowIndex >= venusInitialIndex) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with XVS accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = venusInitialIndex;\\n }\\n // Calculate change in the cumulative sum of the XVS per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n uint256 borrowerDelta = mul_(div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex);\\n venusAccrued[borrower] = add_(venusAccrued[borrower], borrowerDelta);\\n emit DistributedBorrowerVenus(VToken(vToken), borrower, borrowerDelta, borrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0xf13ee35960223103dfc4a661771ae73998d4d4ff5b27f37bbaa52409bbc6103b\"},\"contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface IPolicyFacet {\\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256);\\n\\n function mintVerify(address vToken, address minter, uint256 mintAmount, uint256 mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256);\\n\\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256);\\n\\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external returns (uint256);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint256 repayAmount,\\n uint256 borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount\\n ) external view returns (uint256);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n uint256 seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external returns (uint256);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external;\\n\\n function transferAllowed(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external returns (uint256);\\n\\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external;\\n\\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);\\n\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) external view returns (uint256, uint256, uint256);\\n\\n function _setVenusSpeeds(\\n VToken[] calldata vTokens,\\n uint256[] calldata supplySpeeds,\\n uint256[] calldata borrowSpeeds\\n ) external;\\n}\\n\",\"keccak256\":\"0xbcbbf088aa79d3fcc6945cfbff35b1f2591a803efa6344da1cbf2575f14713be\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport { VTokenInterface } from \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function mintVAI(uint256 mintVAIAmount) external returns (uint256);\\n\\n function repayVAI(uint256 amount) external returns (uint256, uint256);\\n\\n function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256);\\n\\n function liquidateVAI(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint256, uint256);\\n\\n function getMintableVAI(address minter) external view returns (uint256, uint256);\\n\\n function getVAIAddress() external view returns (address);\\n\\n function getVAIRepayAmount(address account) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x1f020ff46cb0efa0ebf563f449fd4d8aa1c8b8ed53c46860d71a08548d7fdfaa\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK,\\n UNLIST_MARKET_NOT_LISTED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0x4f5a41ef380336395706659e2b8f315870dcf3d617ea6f81104424500b15b1ef\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061369b806100206000396000f3fe608060405234801561001057600080fd5b50600436106103af5760003560e01c80637d172bd5116101f4578063c5b4db551161011a578063e37d4b79116100ad578063ead1a8a01161007c578063ead1a8a014610b88578063f445d70314610c96578063f851a44014610cc4578063fa6331d814610ccc576103af565b8063e37d4b7914610af5578063e85a296014610b1b578063e875544614610b4a578063eabe7d9114610b52576103af565b8063d3270f99116100e9578063d3270f9914610a83578063da3d454c14610a8b578063dce1544914610ac1578063dcfbc0c714610aed576103af565b8063c5b4db5514610a09578063c5f956af14610a2d578063c7ee005e14610a35578063d02f735114610a3d576103af565b80639bb27d6211610192578063bbb8864a11610161578063bbb8864a14610997578063bdcdc258146109bd578063bec04f72146109f9578063bf32442d14610a01576103af565b80639bb27d6214610931578063b2eafc3914610939578063b8324c7c14610941578063bb82aa5e1461098f576103af565b80638c1ac18a116101ce5780638c1ac18a146108b35780638e8f294b146108d95780639254f5e51461092157806394b2294b14610929576103af565b80637d172bd51461087d5780637dc0d1d0146108855780638a7dc1651461088d576103af565b806347ef3b3b116102d95780635c778605116102775780636a56947e116102465780636a56947e146107eb5780636d35bf9114610827578063719f701b1461086d5780637655138314610875576103af565b80635c778605146107235780635dd3fc9d146107595780635ec88c791461077f5780635fc7e71e146107a5576103af565b80634e79238f116102b35780634e79238f1461063a5780634ef4c3e11461069457806351dff989146106ca57806352d84d1e14610706576103af565b806347ef3b3b146105c05780634a5844321461060c5780634ada90af14610632576103af565b806324008a62116103515780634088c73e116103205780634088c73e1461054657806341a18d2c1461054e57806341c728b91461057c578063425fad58146105b8576103af565b806324008a62146104d457806324a3d6221461051057806326782247146105185780632bc7e29e14610520576103af565b80630db4b4e51161038d5780630db4b4e51461042257806310b983381461042a5780631ededc911461046c57806321af4569146104b0576103af565b806302c3bcbb146103b457806304ef9d58146103ec57806308e0225c146103f4575b600080fd5b6103da600480360360208110156103ca57600080fd5b50356001600160a01b0316610cd4565b60408051918252519081900360200190f35b6103da610ce6565b6103da6004803603604081101561040a57600080fd5b506001600160a01b0381358116916020013516610cec565b6103da610d09565b6104586004803603604081101561044057600080fd5b506001600160a01b0381358116916020013516610d0f565b604080519115158252519081900360200190f35b6104ae600480360360a081101561048257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135610d2f565b005b6104b8610db6565b604080516001600160a01b039092168252519081900360200190f35b6103da600480360360808110156104ea57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610dc5565b6104b8610e9a565b6104b8610ea9565b6103da6004803603602081101561053657600080fd5b50356001600160a01b0316610eb8565b610458610eca565b6103da6004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610ed3565b6104ae6004803603608081101561059257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610ef0565b610458610f76565b6104ae600480360360c08110156105d657600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135610f85565b6103da6004803603602081101561062257600080fd5b50356001600160a01b031661107b565b6103da61108d565b6106766004803603608081101561065057600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611093565b60408051938452602084019290925282820152519081900360600190f35b6103da600480360360608110156106aa57600080fd5b506001600160a01b038135811691602081013590911690604001356110c9565b6104ae600480360360808110156106e057600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112cf565b6104b86004803603602081101561071c57600080fd5b5035611320565b6104ae6004803603606081101561073957600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6103da6004803603602081101561076f57600080fd5b50356001600160a01b03166113cc565b6106766004803603602081101561079557600080fd5b50356001600160a01b03166113de565b6103da600480360360a08110156107bb57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611413565b6104ae6004803603608081101561080157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356116ae565b6104ae600480360360a081101561083d57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611783565b6103da611858565b61045861185e565b6104b861186c565b6104b861187b565b6103da600480360360208110156108a357600080fd5b50356001600160a01b031661188a565b610458600480360360208110156108c957600080fd5b50356001600160a01b031661189c565b6108ff600480360360208110156108ef57600080fd5b50356001600160a01b03166118b1565b6040805193151584526020840192909252151582820152519081900360600190f35b6104b86118d7565b6103da6118e6565b6104b86118ec565b6104b86118fb565b6109676004803603602081101561095757600080fd5b50356001600160a01b031661190a565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104b8611934565b6103da600480360360208110156109ad57600080fd5b50356001600160a01b0316611943565b6103da600480360360808110156109d357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611955565b6103da6119a3565b6104b86119a9565b610a116119b8565b604080516001600160e01b039092168252519081900360200190f35b6104b86119ca565b6104b86119d9565b6103da600480360360a0811015610a5357600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356119e8565b6104b8611b91565b6103da60048036036060811015610aa157600080fd5b506001600160a01b03813581169160208101359091169060400135611ba0565b6104b860048036036040811015610ad757600080fd5b506001600160a01b038135169060200135611f39565b6104b8611f6e565b61096760048036036020811015610b0b57600080fd5b50356001600160a01b0316611f7d565b61045860048036036040811015610b3157600080fd5b5080356001600160a01b0316906020013560ff16611fa7565b6103da611fe9565b6103da60048036036060811015610b6857600080fd5b506001600160a01b03813581169160208101359091169060400135611fef565b6104ae60048036036060811015610b9e57600080fd5b810190602081018135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460208302840111600160201b83111715610beb57600080fd5b919390929091602081019035600160201b811115610c0857600080fd5b820183602082011115610c1a57600080fd5b803590602001918460208302840111600160201b83111715610c3b57600080fd5b919390929091602081019035600160201b811115610c5857600080fd5b820183602082011115610c6a57600080fd5b803590602001918460208302840111600160201b83111715610c8b57600080fd5b50909250905061203e565b61045860048036036040811015610cac57600080fd5b506001600160a01b0381358116916020013516612117565b6104b8612137565b6103da612146565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03868116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050505b5050505050565b601e546001600160a01b031681565b6000610dcf61214c565b610dda8560036121a1565b6001600160a01b0385166000908152600960205260409020610dfb906121f4565b610e03613629565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4757600080fd5b505afa158015610e5b573d6000803e3d6000fd5b505050506040513d6020811015610e7157600080fd5b505190529050610e818682612241565b610e8c8685836123f7565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610f5757600080fd5b505af1158015610f6b573d6000803e3d6000fd5b505050505b50505050565b60185462010000900460ff1681565b6031546001600160a01b03161561107357603154604080516367994e8b60e11b81526001600160a01b03868116600483015289811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0389811660048301528b81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b15801561105a57600080fd5b505af115801561106e573d6000803e3d6000fd5b505050505b505050505050565b601f6020526000908152604090205481565b60065481565b6000806000806000806110a88a8a8a8a612597565b9250925092508260138111156110ba57fe5b9a919950975095505050505050565b60006110d361214c565b6110de8460006121a1565b6001600160a01b03841660009081526009602052604090206110ff906121f4565b6001600160a01b03841660009081526027602052604090205480611163576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420737570706c792063617020697320360541b604482015290519081900360640190fd5b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119e57600080fd5b505afa1580156111b2573d6000803e3d6000fd5b505050506040513d60208110156111c857600080fd5b505190506111d4613629565b6040518060200160405280886001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561121857600080fd5b505afa15801561122c573d6000803e3d6000fd5b505050506040513d602081101561124257600080fd5b5051905290506000611255828488612656565b9050838111156112ac576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420737570706c7920636170207265616368656400000000000000604482015290519081900360640190fd5b6112b58861267e565b6112bf888861280a565b60009450505050505b9392505050565b801515806112db575081155b610ef0576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d818154811061132d57fe5b6000918252602090912001546001600160a01b0316905081565b6031546001600160a01b0316156113c757603154604080516367994e8b60e11b81526001600160a01b03858116600483015286811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156113ae57600080fd5b505af11580156113c2573d6000803e3d6000fd5b505050505b505050565b602b6020526000908152604090205481565b6000806000806000806113f5876000806000612597565b92509250925082601381111561140757fe5b97919650945092505050565b600061141d61214c565b6114288660056121a1565b6025546001600160a01b03161580159061145057506025546001600160a01b03858116911614155b1561145d575060016116a5565b6001600160a01b038516600090815260096020526040902061147e906121f4565b6015546000906001600160a01b03888116911614611540576001600160a01b03871660009081526009602052604090206114b7906121f4565b866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b505190506115bc565b60155460408051633c617c9160e11b81526001600160a01b038781166004830152915191909216916378c2f922916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505190505b6001600160a01b0387166000908152602d602052604090205460ff168061160857506001600160a01b038085166000908152603260209081526040808320938b168352929052205460ff165b1561162757808311156116205760115b9150506116a5565b6000611618565b600080611638866000806000612597565b9193509091506000905082601381111561164e57fe5b146116695781601381111561165f57fe5b93505050506116a5565b8061167557600361165f565b61168f6040518060200160405280600554815250846129d2565b85111561169d57601161165f565b600093505050505b95945050505050565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b15801561171557600080fd5b505af1158015611729573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0387811660048301528981166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610f5757600080fd5b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03858116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156117ea57600080fd5b505af11580156117fe573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0388811660048301528a81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610d9657600080fd5b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b60075481565b6025546001600160a01b031681565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b600061195f61214c565b61196a8560066121a1565b60006119778686856129f1565b90508015611986579050610e92565b61198f8661267e565b611999868661280a565b610e8c868561280a565b60175481565b6033546001600160a01b031690565b6a0c097ce7bc90715b34b9f160241b81565b6021546001600160a01b031681565b6031546001600160a01b031681565b60006119f261214c565b6119fd8660046121a1565b6001600160a01b0386166000908152600960205260409020611a1e816121f4565b6001600160a01b038416600090815260028201602052604090205460ff16611a47576013611618565b6015546001600160a01b03878116911614611a7d576001600160a01b0386166000908152600960205260409020611a7d906121f4565b856001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505160408051635fe3b56760e01b815290516001600160a01b03928316928a1691635fe3b567916004808301926020929190829003018186803b158015611b2657600080fd5b505afa158015611b3a573d6000803e3d6000fd5b505050506040513d6020811015611b5057600080fd5b50516001600160a01b031614611b67576002611618565b611b708761267e565b611b7a878561280a565b611b84878661280a565b6000979650505050505050565b6026546001600160a01b031681565b6000611baa61214c565b611bb58460026121a1565b6001600160a01b0384166000908152600960205260409020611bd6906121f4565b6001600160a01b0384166000908152601f602052604090205480611c3a576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420626f72726f772063617020697320360541b604482015290519081900360640190fd5b6001600160a01b038086166000908152600960209081526040808320938816835260029093019052205460ff16611cf857336001600160a01b03861614611cc0576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba103132903b2a37b5b2b760591b604482015290519081900360640190fd5b6000611ccc8686612a9b565b90506000816013811115611cdc57fe5b14611cf657806013811115611ced57fe5b925050506112c8565b505b600480546040805163fc57d4df60e01b81526001600160a01b03898116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015611d4957600080fd5b505afa158015611d5d573d6000803e3d6000fd5b505050506040513d6020811015611d7357600080fd5b5051611d8357600d9150506112c8565b6000611df3866001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015611dc157600080fd5b505afa158015611dd5573d6000803e3d6000fd5b505050506040513d6020811015611deb57600080fd5b505185612b7f565b905081811115611e4a576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b600080611e5a8789600089612597565b91935090915060009050826013811115611e7057fe5b14611e8c57816013811115611e8157fe5b9450505050506112c8565b8015611e99576004611e81565b611ea1613629565b60405180602001604052808a6001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ee557600080fd5b505afa158015611ef9573d6000803e3d6000fd5b505050506040513d6020811015611f0f57600080fd5b505190529050611f1f8982612241565b611f2a8989836123f7565b60009998505050505050505050565b60086020528160005260406000208181548110611f5257fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b038216600090815260296020526040812081836008811115611fcc57fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b6000611ff961214c565b6120048460016121a1565b60006120118585856129f1565b905080156120205790506112c8565b6120298561267e565b612033858561280a565b600095945050505050565b612046612bb5565b84838114801561205557508082145b612096576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b81811015610f6b576120c58888838181106120b057fe5b905060200201356001600160a01b0316612c05565b61210f8888838181106120d457fe5b905060200201356001600160a01b03168787848181106120f057fe5b9050602002013586868581811061210357fe5b90506020020135612c58565b600101612099565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b60185462010000900460ff161561219f576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b565b6121ab8282611fa7565b156121f0576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b5050565b805460ff1661223e576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b50565b6001600160a01b0382166000908152601160209081526040808320602a909252822054909161226e612ded565b83549091506000906122909063ffffffff80851691600160e01b900416612e2e565b905080158015906122a057508215155b156123cc576000612315876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156122e357600080fd5b505afa1580156122f7573d6000803e3d6000fd5b505050506040513d602081101561230d57600080fd5b505187612e68565b905060006123238386612e86565b905061232d613629565b826123475760405180602001604052806000815250612351565b6123518284612ec8565b604080516020810190915288546001600160e01b0316815290915061239a9061237a9083612f05565b516040805180820190915260038152620c8c8d60ea1b6020820152612f2a565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611073915050565b801561107357835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b601b546001600160a01b03161561241057612410612fc4565b6001600160a01b0383811660009081526011602090815260408083205460138352818420948716845293909152902080546001600160e01b0390921690819055908015801561246d57506a0c097ce7bc90715b34b9f160241b8210155b1561248357506a0c097ce7bc90715b34b9f160241b5b61248b613629565b60405180602001604052806124a08585612e2e565b81525090506000612509612503886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156122e357600080fd5b8361316c565b6001600160a01b03871660009081526014602052604090205490915061252f9082612b7f565b6001600160a01b0380881660008181526014602090815260409182902094909455805185815293840188905280519193928b16927f837bdc11fca9f17ce44167944475225a205279b17e88c791c3b1f66f354668fb929081900390910190a350505050505050565b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b15801561260a57600080fd5b505afa15801561261e573d6000803e3d6000fd5b505050506040513d606081101561263457600080fd5b508051602082015160409092015190945090925090508260138111156110ba57fe5b6000612660613629565b61266a858561319a565b90506116a5612678826131bb565b84612b7f565b6001600160a01b0381166000908152601060209081526040808320602b90925282205490916126ab612ded565b83549091506000906126cd9063ffffffff80851691600160e01b900416612e2e565b905080158015906126dd57508215155b156127e0576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561271d57600080fd5b505afa158015612731573d6000803e3d6000fd5b505050506040513d602081101561274757600080fd5b5051905060006127578386612e86565b9050612761613629565b8261277b5760405180602001604052806000815250612785565b6127858284612ec8565b604080516020810190915288546001600160e01b031681529091506127ae9061237a9083612f05565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550610daf915050565b8015610daf57835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b601b546001600160a01b03161561282357612823612fc4565b6001600160a01b0382811660009081526010602090815260408083205460128352818420948616845293909152902080546001600160e01b0390921690819055908015801561288057506a0c097ce7bc90715b34b9f160241b8210155b1561289657506a0c097ce7bc90715b34b9f160241b5b61289e613629565b60405180602001604052806128b38585612e2e565b81525090506000612945866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561291357600080fd5b505afa158015612927573d6000803e3d6000fd5b505050506040513d602081101561293d57600080fd5b50518361316c565b6001600160a01b03861660009081526014602052604090205490915061296b9082612b7f565b6001600160a01b0380871660008181526014602090815260409182902094909455805185815293840188905280519193928a16927ffa9d964d891991c113b49e3db1932abd6c67263d387119707aafdd6c4010a3a9929081900390910190a3505050505050565b60006129dc613629565b6129e6848461319a565b9050610e92816131bb565b6001600160a01b0383166000908152600960205260408120612a12906121f4565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16612a4b575060006112c8565b600080612a5b8587866000612597565b91935090915060009050826013811115612a7157fe5b14612a8257816013811115611ced57fe5b8015612a8f576004611ced565b60009695505050505050565b6000612aa88360076121a1565b6001600160a01b0383166000908152600960205260409020612ac9816121f4565b6001600160a01b038316600090815260028201602052604090205460ff1615612af6576000915050611fe3565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b60006112c88383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b8152506131ca565b6000546001600160a01b0316331461219f576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b6001600160a01b03811661223e576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612c79906121f4565b6001600160a01b0383166000908152602b60205260409020548214612cf257612ca18361267e565b6001600160a01b0383166000818152602b6020908152604091829020859055815185815291517fa9ff26899e4982e7634afa9f70115dcfb61a17d6e8cdd91aa837671d0ff40ba69281900390910190a25b6001600160a01b0383166000908152602a602052604090205481146113c757612d19613629565b6040518060200160405280856001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d5d57600080fd5b505afa158015612d71573d6000803e3d6000fd5b505050506040513d6020811015612d8757600080fd5b505190529050612d978482612241565b6001600160a01b0384166000818152602a6020908152604091829020859055815185815291517f0c62c1bc89ec4c40dccb4d21543e782c5ba43897c0075d108d8964181ea3c51b9281900390910190a250505050565b6000612e29612dfa613228565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b81525061322c565b905090565b60006112c88383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250613281565b60006112c8612e7f84670de0b6b3a7640000612e86565b83516132db565b60006112c883836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f7700000000000000000081525061330e565b612ed0613629565b6040518060200160405280612efc612ef6866a0c097ce7bc90715b34b9f160241b612e86565b856132db565b90529392505050565b612f0d613629565b6040518060200160405280612efc85600001518560000151612b7f565b600081600160e01b8410612fbc5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612f81578181015183820152602001612f69565b50505050905090810190601f168015612fae5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b601c541580612fdb5750601c54612fd9613228565b105b15612fe55761219f565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561303557600080fd5b505afa158015613049573d6000803e3d6000fd5b505050506040513d602081101561305f57600080fd5b505190508061306f57505061219f565b60008061308561307d613228565b601c54612e2e565b90506000613095601a5483612e86565b90508084106130a6578092506130aa565b8392505b601d548310156130be57505050505061219f565b6130c6613228565b601c55601b546130e9906001600160a01b0387811691168563ffffffff61338416565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d9657600080fd5b60006a0c097ce7bc90715b34b9f160241b61318b848460000151612e86565b8161319257fe5b049392505050565b6131a2613629565b6040518060200160405280612efc856000015185612e86565b51670de0b6b3a7640000900490565b6000838301828582101561321f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b50949350505050565b4390565b600081600160201b8410612fbc5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b600081848411156132d35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b505050900390565b60006112c883836040518060400160405280600e81526020016d646976696465206279207a65726f60901b8152506133d6565b600083158061331b575082155b15613328575060006112c8565b8383028385828161333557fe5b0414839061321f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113c7908490613438565b600081836134255760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b5082848161342f57fe5b04949350505050565b61344a826001600160a01b03166135f0565b61349b576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106134d95780518252601f1990920191602091820191016134ba565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461353b576040519150601f19603f3d011682016040523d82523d6000602084013e613540565b606091505b509150915081613597576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610f70578080602001905160208110156135b357600080fd5b5051610f705760405162461bcd60e51b815260040180806020018281038252602a81526020018061363d602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e92575050151592915050565b604051806020016040528060008152509056fe5361666542455032303a204245503230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a723158203f58b21f29192df605dc656de953c22c19c0c55e6740cb388aa793a126d9ecb464736f6c63430005100032", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103af5760003560e01c80637d172bd5116101f4578063c5b4db551161011a578063e37d4b79116100ad578063ead1a8a01161007c578063ead1a8a014610b88578063f445d70314610c96578063f851a44014610cc4578063fa6331d814610ccc576103af565b8063e37d4b7914610af5578063e85a296014610b1b578063e875544614610b4a578063eabe7d9114610b52576103af565b8063d3270f99116100e9578063d3270f9914610a83578063da3d454c14610a8b578063dce1544914610ac1578063dcfbc0c714610aed576103af565b8063c5b4db5514610a09578063c5f956af14610a2d578063c7ee005e14610a35578063d02f735114610a3d576103af565b80639bb27d6211610192578063bbb8864a11610161578063bbb8864a14610997578063bdcdc258146109bd578063bec04f72146109f9578063bf32442d14610a01576103af565b80639bb27d6214610931578063b2eafc3914610939578063b8324c7c14610941578063bb82aa5e1461098f576103af565b80638c1ac18a116101ce5780638c1ac18a146108b35780638e8f294b146108d95780639254f5e51461092157806394b2294b14610929576103af565b80637d172bd51461087d5780637dc0d1d0146108855780638a7dc1651461088d576103af565b806347ef3b3b116102d95780635c778605116102775780636a56947e116102465780636a56947e146107eb5780636d35bf9114610827578063719f701b1461086d5780637655138314610875576103af565b80635c778605146107235780635dd3fc9d146107595780635ec88c791461077f5780635fc7e71e146107a5576103af565b80634e79238f116102b35780634e79238f1461063a5780634ef4c3e11461069457806351dff989146106ca57806352d84d1e14610706576103af565b806347ef3b3b146105c05780634a5844321461060c5780634ada90af14610632576103af565b806324008a62116103515780634088c73e116103205780634088c73e1461054657806341a18d2c1461054e57806341c728b91461057c578063425fad58146105b8576103af565b806324008a62146104d457806324a3d6221461051057806326782247146105185780632bc7e29e14610520576103af565b80630db4b4e51161038d5780630db4b4e51461042257806310b983381461042a5780631ededc911461046c57806321af4569146104b0576103af565b806302c3bcbb146103b457806304ef9d58146103ec57806308e0225c146103f4575b600080fd5b6103da600480360360208110156103ca57600080fd5b50356001600160a01b0316610cd4565b60408051918252519081900360200190f35b6103da610ce6565b6103da6004803603604081101561040a57600080fd5b506001600160a01b0381358116916020013516610cec565b6103da610d09565b6104586004803603604081101561044057600080fd5b506001600160a01b0381358116916020013516610d0f565b604080519115158252519081900360200190f35b6104ae600480360360a081101561048257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135610d2f565b005b6104b8610db6565b604080516001600160a01b039092168252519081900360200190f35b6103da600480360360808110156104ea57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610dc5565b6104b8610e9a565b6104b8610ea9565b6103da6004803603602081101561053657600080fd5b50356001600160a01b0316610eb8565b610458610eca565b6103da6004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610ed3565b6104ae6004803603608081101561059257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610ef0565b610458610f76565b6104ae600480360360c08110156105d657600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135610f85565b6103da6004803603602081101561062257600080fd5b50356001600160a01b031661107b565b6103da61108d565b6106766004803603608081101561065057600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611093565b60408051938452602084019290925282820152519081900360600190f35b6103da600480360360608110156106aa57600080fd5b506001600160a01b038135811691602081013590911690604001356110c9565b6104ae600480360360808110156106e057600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112cf565b6104b86004803603602081101561071c57600080fd5b5035611320565b6104ae6004803603606081101561073957600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6103da6004803603602081101561076f57600080fd5b50356001600160a01b03166113cc565b6106766004803603602081101561079557600080fd5b50356001600160a01b03166113de565b6103da600480360360a08110156107bb57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611413565b6104ae6004803603608081101561080157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356116ae565b6104ae600480360360a081101561083d57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611783565b6103da611858565b61045861185e565b6104b861186c565b6104b861187b565b6103da600480360360208110156108a357600080fd5b50356001600160a01b031661188a565b610458600480360360208110156108c957600080fd5b50356001600160a01b031661189c565b6108ff600480360360208110156108ef57600080fd5b50356001600160a01b03166118b1565b6040805193151584526020840192909252151582820152519081900360600190f35b6104b86118d7565b6103da6118e6565b6104b86118ec565b6104b86118fb565b6109676004803603602081101561095757600080fd5b50356001600160a01b031661190a565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104b8611934565b6103da600480360360208110156109ad57600080fd5b50356001600160a01b0316611943565b6103da600480360360808110156109d357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611955565b6103da6119a3565b6104b86119a9565b610a116119b8565b604080516001600160e01b039092168252519081900360200190f35b6104b86119ca565b6104b86119d9565b6103da600480360360a0811015610a5357600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356119e8565b6104b8611b91565b6103da60048036036060811015610aa157600080fd5b506001600160a01b03813581169160208101359091169060400135611ba0565b6104b860048036036040811015610ad757600080fd5b506001600160a01b038135169060200135611f39565b6104b8611f6e565b61096760048036036020811015610b0b57600080fd5b50356001600160a01b0316611f7d565b61045860048036036040811015610b3157600080fd5b5080356001600160a01b0316906020013560ff16611fa7565b6103da611fe9565b6103da60048036036060811015610b6857600080fd5b506001600160a01b03813581169160208101359091169060400135611fef565b6104ae60048036036060811015610b9e57600080fd5b810190602081018135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460208302840111600160201b83111715610beb57600080fd5b919390929091602081019035600160201b811115610c0857600080fd5b820183602082011115610c1a57600080fd5b803590602001918460208302840111600160201b83111715610c3b57600080fd5b919390929091602081019035600160201b811115610c5857600080fd5b820183602082011115610c6a57600080fd5b803590602001918460208302840111600160201b83111715610c8b57600080fd5b50909250905061203e565b61045860048036036040811015610cac57600080fd5b506001600160a01b0381358116916020013516612117565b6104b8612137565b6103da612146565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03868116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050505b5050505050565b601e546001600160a01b031681565b6000610dcf61214c565b610dda8560036121a1565b6001600160a01b0385166000908152600960205260409020610dfb906121f4565b610e03613629565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4757600080fd5b505afa158015610e5b573d6000803e3d6000fd5b505050506040513d6020811015610e7157600080fd5b505190529050610e818682612241565b610e8c8685836123f7565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610f5757600080fd5b505af1158015610f6b573d6000803e3d6000fd5b505050505b50505050565b60185462010000900460ff1681565b6031546001600160a01b03161561107357603154604080516367994e8b60e11b81526001600160a01b03868116600483015289811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0389811660048301528b81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b15801561105a57600080fd5b505af115801561106e573d6000803e3d6000fd5b505050505b505050505050565b601f6020526000908152604090205481565b60065481565b6000806000806000806110a88a8a8a8a612597565b9250925092508260138111156110ba57fe5b9a919950975095505050505050565b60006110d361214c565b6110de8460006121a1565b6001600160a01b03841660009081526009602052604090206110ff906121f4565b6001600160a01b03841660009081526027602052604090205480611163576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420737570706c792063617020697320360541b604482015290519081900360640190fd5b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119e57600080fd5b505afa1580156111b2573d6000803e3d6000fd5b505050506040513d60208110156111c857600080fd5b505190506111d4613629565b6040518060200160405280886001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561121857600080fd5b505afa15801561122c573d6000803e3d6000fd5b505050506040513d602081101561124257600080fd5b5051905290506000611255828488612656565b9050838111156112ac576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420737570706c7920636170207265616368656400000000000000604482015290519081900360640190fd5b6112b58861267e565b6112bf888861280a565b60009450505050505b9392505050565b801515806112db575081155b610ef0576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d818154811061132d57fe5b6000918252602090912001546001600160a01b0316905081565b6031546001600160a01b0316156113c757603154604080516367994e8b60e11b81526001600160a01b03858116600483015286811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156113ae57600080fd5b505af11580156113c2573d6000803e3d6000fd5b505050505b505050565b602b6020526000908152604090205481565b6000806000806000806113f5876000806000612597565b92509250925082601381111561140757fe5b97919650945092505050565b600061141d61214c565b6114288660056121a1565b6025546001600160a01b03161580159061145057506025546001600160a01b03858116911614155b1561145d575060016116a5565b6001600160a01b038516600090815260096020526040902061147e906121f4565b6015546000906001600160a01b03888116911614611540576001600160a01b03871660009081526009602052604090206114b7906121f4565b866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b505190506115bc565b60155460408051633c617c9160e11b81526001600160a01b038781166004830152915191909216916378c2f922916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505190505b6001600160a01b0387166000908152602d602052604090205460ff168061160857506001600160a01b038085166000908152603260209081526040808320938b168352929052205460ff165b1561162757808311156116205760115b9150506116a5565b6000611618565b600080611638866000806000612597565b9193509091506000905082601381111561164e57fe5b146116695781601381111561165f57fe5b93505050506116a5565b8061167557600361165f565b61168f6040518060200160405280600554815250846129d2565b85111561169d57601161165f565b600093505050505b95945050505050565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b15801561171557600080fd5b505af1158015611729573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0387811660048301528981166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610f5757600080fd5b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03858116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156117ea57600080fd5b505af11580156117fe573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0388811660048301528a81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610d9657600080fd5b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b60075481565b6025546001600160a01b031681565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b600061195f61214c565b61196a8560066121a1565b60006119778686856129f1565b90508015611986579050610e92565b61198f8661267e565b611999868661280a565b610e8c868561280a565b60175481565b6033546001600160a01b031690565b6a0c097ce7bc90715b34b9f160241b81565b6021546001600160a01b031681565b6031546001600160a01b031681565b60006119f261214c565b6119fd8660046121a1565b6001600160a01b0386166000908152600960205260409020611a1e816121f4565b6001600160a01b038416600090815260028201602052604090205460ff16611a47576013611618565b6015546001600160a01b03878116911614611a7d576001600160a01b0386166000908152600960205260409020611a7d906121f4565b856001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505160408051635fe3b56760e01b815290516001600160a01b03928316928a1691635fe3b567916004808301926020929190829003018186803b158015611b2657600080fd5b505afa158015611b3a573d6000803e3d6000fd5b505050506040513d6020811015611b5057600080fd5b50516001600160a01b031614611b67576002611618565b611b708761267e565b611b7a878561280a565b611b84878661280a565b6000979650505050505050565b6026546001600160a01b031681565b6000611baa61214c565b611bb58460026121a1565b6001600160a01b0384166000908152600960205260409020611bd6906121f4565b6001600160a01b0384166000908152601f602052604090205480611c3a576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420626f72726f772063617020697320360541b604482015290519081900360640190fd5b6001600160a01b038086166000908152600960209081526040808320938816835260029093019052205460ff16611cf857336001600160a01b03861614611cc0576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba103132903b2a37b5b2b760591b604482015290519081900360640190fd5b6000611ccc8686612a9b565b90506000816013811115611cdc57fe5b14611cf657806013811115611ced57fe5b925050506112c8565b505b600480546040805163fc57d4df60e01b81526001600160a01b03898116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015611d4957600080fd5b505afa158015611d5d573d6000803e3d6000fd5b505050506040513d6020811015611d7357600080fd5b5051611d8357600d9150506112c8565b6000611df3866001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015611dc157600080fd5b505afa158015611dd5573d6000803e3d6000fd5b505050506040513d6020811015611deb57600080fd5b505185612b7f565b905081811115611e4a576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b600080611e5a8789600089612597565b91935090915060009050826013811115611e7057fe5b14611e8c57816013811115611e8157fe5b9450505050506112c8565b8015611e99576004611e81565b611ea1613629565b60405180602001604052808a6001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ee557600080fd5b505afa158015611ef9573d6000803e3d6000fd5b505050506040513d6020811015611f0f57600080fd5b505190529050611f1f8982612241565b611f2a8989836123f7565b60009998505050505050505050565b60086020528160005260406000208181548110611f5257fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b038216600090815260296020526040812081836008811115611fcc57fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b6000611ff961214c565b6120048460016121a1565b60006120118585856129f1565b905080156120205790506112c8565b6120298561267e565b612033858561280a565b600095945050505050565b612046612bb5565b84838114801561205557508082145b612096576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b81811015610f6b576120c58888838181106120b057fe5b905060200201356001600160a01b0316612c05565b61210f8888838181106120d457fe5b905060200201356001600160a01b03168787848181106120f057fe5b9050602002013586868581811061210357fe5b90506020020135612c58565b600101612099565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b60185462010000900460ff161561219f576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b565b6121ab8282611fa7565b156121f0576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b5050565b805460ff1661223e576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b50565b6001600160a01b0382166000908152601160209081526040808320602a909252822054909161226e612ded565b83549091506000906122909063ffffffff80851691600160e01b900416612e2e565b905080158015906122a057508215155b156123cc576000612315876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156122e357600080fd5b505afa1580156122f7573d6000803e3d6000fd5b505050506040513d602081101561230d57600080fd5b505187612e68565b905060006123238386612e86565b905061232d613629565b826123475760405180602001604052806000815250612351565b6123518284612ec8565b604080516020810190915288546001600160e01b0316815290915061239a9061237a9083612f05565b516040805180820190915260038152620c8c8d60ea1b6020820152612f2a565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611073915050565b801561107357835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b601b546001600160a01b03161561241057612410612fc4565b6001600160a01b0383811660009081526011602090815260408083205460138352818420948716845293909152902080546001600160e01b0390921690819055908015801561246d57506a0c097ce7bc90715b34b9f160241b8210155b1561248357506a0c097ce7bc90715b34b9f160241b5b61248b613629565b60405180602001604052806124a08585612e2e565b81525090506000612509612503886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156122e357600080fd5b8361316c565b6001600160a01b03871660009081526014602052604090205490915061252f9082612b7f565b6001600160a01b0380881660008181526014602090815260409182902094909455805185815293840188905280519193928b16927f837bdc11fca9f17ce44167944475225a205279b17e88c791c3b1f66f354668fb929081900390910190a350505050505050565b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b15801561260a57600080fd5b505afa15801561261e573d6000803e3d6000fd5b505050506040513d606081101561263457600080fd5b508051602082015160409092015190945090925090508260138111156110ba57fe5b6000612660613629565b61266a858561319a565b90506116a5612678826131bb565b84612b7f565b6001600160a01b0381166000908152601060209081526040808320602b90925282205490916126ab612ded565b83549091506000906126cd9063ffffffff80851691600160e01b900416612e2e565b905080158015906126dd57508215155b156127e0576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561271d57600080fd5b505afa158015612731573d6000803e3d6000fd5b505050506040513d602081101561274757600080fd5b5051905060006127578386612e86565b9050612761613629565b8261277b5760405180602001604052806000815250612785565b6127858284612ec8565b604080516020810190915288546001600160e01b031681529091506127ae9061237a9083612f05565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550610daf915050565b8015610daf57835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b601b546001600160a01b03161561282357612823612fc4565b6001600160a01b0382811660009081526010602090815260408083205460128352818420948616845293909152902080546001600160e01b0390921690819055908015801561288057506a0c097ce7bc90715b34b9f160241b8210155b1561289657506a0c097ce7bc90715b34b9f160241b5b61289e613629565b60405180602001604052806128b38585612e2e565b81525090506000612945866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561291357600080fd5b505afa158015612927573d6000803e3d6000fd5b505050506040513d602081101561293d57600080fd5b50518361316c565b6001600160a01b03861660009081526014602052604090205490915061296b9082612b7f565b6001600160a01b0380871660008181526014602090815260409182902094909455805185815293840188905280519193928a16927ffa9d964d891991c113b49e3db1932abd6c67263d387119707aafdd6c4010a3a9929081900390910190a3505050505050565b60006129dc613629565b6129e6848461319a565b9050610e92816131bb565b6001600160a01b0383166000908152600960205260408120612a12906121f4565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16612a4b575060006112c8565b600080612a5b8587866000612597565b91935090915060009050826013811115612a7157fe5b14612a8257816013811115611ced57fe5b8015612a8f576004611ced565b60009695505050505050565b6000612aa88360076121a1565b6001600160a01b0383166000908152600960205260409020612ac9816121f4565b6001600160a01b038316600090815260028201602052604090205460ff1615612af6576000915050611fe3565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b60006112c88383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b8152506131ca565b6000546001600160a01b0316331461219f576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b6001600160a01b03811661223e576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612c79906121f4565b6001600160a01b0383166000908152602b60205260409020548214612cf257612ca18361267e565b6001600160a01b0383166000818152602b6020908152604091829020859055815185815291517fa9ff26899e4982e7634afa9f70115dcfb61a17d6e8cdd91aa837671d0ff40ba69281900390910190a25b6001600160a01b0383166000908152602a602052604090205481146113c757612d19613629565b6040518060200160405280856001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d5d57600080fd5b505afa158015612d71573d6000803e3d6000fd5b505050506040513d6020811015612d8757600080fd5b505190529050612d978482612241565b6001600160a01b0384166000818152602a6020908152604091829020859055815185815291517f0c62c1bc89ec4c40dccb4d21543e782c5ba43897c0075d108d8964181ea3c51b9281900390910190a250505050565b6000612e29612dfa613228565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b81525061322c565b905090565b60006112c88383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250613281565b60006112c8612e7f84670de0b6b3a7640000612e86565b83516132db565b60006112c883836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f7700000000000000000081525061330e565b612ed0613629565b6040518060200160405280612efc612ef6866a0c097ce7bc90715b34b9f160241b612e86565b856132db565b90529392505050565b612f0d613629565b6040518060200160405280612efc85600001518560000151612b7f565b600081600160e01b8410612fbc5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612f81578181015183820152602001612f69565b50505050905090810190601f168015612fae5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b601c541580612fdb5750601c54612fd9613228565b105b15612fe55761219f565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561303557600080fd5b505afa158015613049573d6000803e3d6000fd5b505050506040513d602081101561305f57600080fd5b505190508061306f57505061219f565b60008061308561307d613228565b601c54612e2e565b90506000613095601a5483612e86565b90508084106130a6578092506130aa565b8392505b601d548310156130be57505050505061219f565b6130c6613228565b601c55601b546130e9906001600160a01b0387811691168563ffffffff61338416565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d9657600080fd5b60006a0c097ce7bc90715b34b9f160241b61318b848460000151612e86565b8161319257fe5b049392505050565b6131a2613629565b6040518060200160405280612efc856000015185612e86565b51670de0b6b3a7640000900490565b6000838301828582101561321f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b50949350505050565b4390565b600081600160201b8410612fbc5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b600081848411156132d35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b505050900390565b60006112c883836040518060400160405280600e81526020016d646976696465206279207a65726f60901b8152506133d6565b600083158061331b575082155b15613328575060006112c8565b8383028385828161333557fe5b0414839061321f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113c7908490613438565b600081836134255760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b5082848161342f57fe5b04949350505050565b61344a826001600160a01b03166135f0565b61349b576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106134d95780518252601f1990920191602091820191016134ba565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461353b576040519150601f19603f3d011682016040523d82523d6000602084013e613540565b606091505b509150915081613597576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610f70578080602001905160208110156135b357600080fd5b5051610f705760405162461bcd60e51b815260040180806020018281038252602a81526020018061363d602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e92575050151592915050565b604051806020016040528060008152509056fe5361666542455032303a204245503230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a723158203f58b21f29192df605dc656de953c22c19c0c55e6740cb388aa793a126d9ecb464736f6c63430005100032", "devdoc": { "author": "Venus", "details": "This facet contains all the hooks used while transferring the assets", @@ -1786,7 +1786,7 @@ "storageLayout": { "storage": [ { - "astId": 2402, + "astId": 2503, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "admin", "offset": 0, @@ -1794,7 +1794,7 @@ "type": "t_address" }, { - "astId": 2404, + "astId": 2505, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "pendingAdmin", "offset": 0, @@ -1802,7 +1802,7 @@ "type": "t_address" }, { - "astId": 2406, + "astId": 2507, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "comptrollerImplementation", "offset": 0, @@ -1810,7 +1810,7 @@ "type": "t_address" }, { - "astId": 2408, + "astId": 2509, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "pendingComptrollerImplementation", "offset": 0, @@ -1818,15 +1818,15 @@ "type": "t_address" }, { - "astId": 2415, + "astId": 2516, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "oracle", "offset": 0, "slot": "4", - "type": "t_contract(PriceOracle)12106" + "type": "t_contract(PriceOracle)12346" }, { - "astId": 2417, + "astId": 2518, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "closeFactorMantissa", "offset": 0, @@ -1834,7 +1834,7 @@ "type": "t_uint256" }, { - "astId": 2419, + "astId": 2520, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "liquidationIncentiveMantissa", "offset": 0, @@ -1842,7 +1842,7 @@ "type": "t_uint256" }, { - "astId": 2421, + "astId": 2522, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "maxAssets", "offset": 0, @@ -1850,23 +1850,23 @@ "type": "t_uint256" }, { - "astId": 2426, + "astId": 2527, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "accountAssets", "offset": 0, "slot": "8", - "type": "t_mapping(t_address,t_array(t_contract(VToken)23033)dyn_storage)" + "type": "t_mapping(t_address,t_array(t_contract(VToken)23484)dyn_storage)" }, { - "astId": 2441, + "astId": 2542, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "markets", "offset": 0, "slot": "9", - "type": "t_mapping(t_address,t_struct(Market)2437_storage)" + "type": "t_mapping(t_address,t_struct(Market)2538_storage)" }, { - "astId": 2443, + "astId": 2544, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "pauseGuardian", "offset": 0, @@ -1874,7 +1874,7 @@ "type": "t_address" }, { - "astId": 2445, + "astId": 2546, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_mintGuardianPaused", "offset": 20, @@ -1882,7 +1882,7 @@ "type": "t_bool" }, { - "astId": 2447, + "astId": 2548, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_borrowGuardianPaused", "offset": 21, @@ -1890,7 +1890,7 @@ "type": "t_bool" }, { - "astId": 2449, + "astId": 2550, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "transferGuardianPaused", "offset": 22, @@ -1898,7 +1898,7 @@ "type": "t_bool" }, { - "astId": 2451, + "astId": 2552, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "seizeGuardianPaused", "offset": 23, @@ -1906,7 +1906,7 @@ "type": "t_bool" }, { - "astId": 2455, + "astId": 2556, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "mintGuardianPaused", "offset": 0, @@ -1914,7 +1914,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2459, + "astId": 2560, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "borrowGuardianPaused", "offset": 0, @@ -1922,15 +1922,15 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2467, + "astId": 2568, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "allMarkets", "offset": 0, "slot": "13", - "type": "t_array(t_contract(VToken)23033)dyn_storage" + "type": "t_array(t_contract(VToken)23484)dyn_storage" }, { - "astId": 2469, + "astId": 2570, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusRate", "offset": 0, @@ -1938,7 +1938,7 @@ "type": "t_uint256" }, { - "astId": 2473, + "astId": 2574, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusSpeeds", "offset": 0, @@ -1946,23 +1946,23 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2477, + "astId": 2578, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusSupplyState", "offset": 0, "slot": "16", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)" }, { - "astId": 2481, + "astId": 2582, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusBorrowState", "offset": 0, "slot": "17", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)" }, { - "astId": 2487, + "astId": 2588, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusSupplierIndex", "offset": 0, @@ -1970,7 +1970,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2493, + "astId": 2594, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusBorrowerIndex", "offset": 0, @@ -1978,7 +1978,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2497, + "astId": 2598, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusAccrued", "offset": 0, @@ -1986,15 +1986,15 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2499, + "astId": 2600, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "vaiController", "offset": 0, "slot": "21", - "type": "t_contract(VAIControllerInterface)15582" + "type": "t_contract(VAIControllerInterface)15644" }, { - "astId": 2503, + "astId": 2604, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "mintedVAIs", "offset": 0, @@ -2002,7 +2002,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2505, + "astId": 2606, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "vaiMintRate", "offset": 0, @@ -2010,7 +2010,7 @@ "type": "t_uint256" }, { - "astId": 2507, + "astId": 2608, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "mintVAIGuardianPaused", "offset": 0, @@ -2018,7 +2018,7 @@ "type": "t_bool" }, { - "astId": 2509, + "astId": 2610, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "repayVAIGuardianPaused", "offset": 1, @@ -2026,7 +2026,7 @@ "type": "t_bool" }, { - "astId": 2511, + "astId": 2612, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "protocolPaused", "offset": 2, @@ -2034,7 +2034,7 @@ "type": "t_bool" }, { - "astId": 2513, + "astId": 2614, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusVAIRate", "offset": 0, @@ -2042,7 +2042,7 @@ "type": "t_uint256" }, { - "astId": 2518, + "astId": 2619, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusVAIVaultRate", "offset": 0, @@ -2050,7 +2050,7 @@ "type": "t_uint256" }, { - "astId": 2520, + "astId": 2621, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "vaiVaultAddress", "offset": 0, @@ -2058,7 +2058,7 @@ "type": "t_address" }, { - "astId": 2522, + "astId": 2623, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "releaseStartBlock", "offset": 0, @@ -2066,7 +2066,7 @@ "type": "t_uint256" }, { - "astId": 2524, + "astId": 2625, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "minReleaseAmount", "offset": 0, @@ -2074,7 +2074,7 @@ "type": "t_uint256" }, { - "astId": 2529, + "astId": 2630, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "borrowCapGuardian", "offset": 0, @@ -2082,7 +2082,7 @@ "type": "t_address" }, { - "astId": 2533, + "astId": 2634, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "borrowCaps", "offset": 0, @@ -2090,7 +2090,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2538, + "astId": 2639, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "treasuryGuardian", "offset": 0, @@ -2098,7 +2098,7 @@ "type": "t_address" }, { - "astId": 2540, + "astId": 2641, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "treasuryAddress", "offset": 0, @@ -2106,7 +2106,7 @@ "type": "t_address" }, { - "astId": 2542, + "astId": 2643, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "treasuryPercent", "offset": 0, @@ -2114,7 +2114,7 @@ "type": "t_uint256" }, { - "astId": 2549, + "astId": 2650, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusContributorSpeeds", "offset": 0, @@ -2122,7 +2122,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2553, + "astId": 2654, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "lastContributorBlock", "offset": 0, @@ -2130,7 +2130,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2558, + "astId": 2659, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "liquidatorContract", "offset": 0, @@ -2138,15 +2138,15 @@ "type": "t_address" }, { - "astId": 2563, + "astId": 2664, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "comptrollerLens", "offset": 0, "slot": "38", - "type": "t_contract(ComptrollerLensInterface)2377" + "type": "t_contract(ComptrollerLensInterface)2478" }, { - "astId": 2570, + "astId": 2671, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "supplyCaps", "offset": 0, @@ -2154,7 +2154,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2575, + "astId": 2676, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "accessControl", "offset": 0, @@ -2162,7 +2162,7 @@ "type": "t_address" }, { - "astId": 2581, + "astId": 2682, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_actionPaused", "offset": 0, @@ -2170,7 +2170,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" }, { - "astId": 2588, + "astId": 2689, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusBorrowSpeeds", "offset": 0, @@ -2178,7 +2178,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2592, + "astId": 2693, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusSupplySpeeds", "offset": 0, @@ -2186,7 +2186,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2601, + "astId": 2702, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "approvedDelegates", "offset": 0, @@ -2194,7 +2194,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2608, + "astId": 2709, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "isForcedLiquidationEnabled", "offset": 0, @@ -2202,23 +2202,23 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2626, + "astId": 2727, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_selectorToFacetAndPosition", "offset": 0, "slot": "46", - "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2616_storage)" + "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2717_storage)" }, { - "astId": 2630, + "astId": 2731, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_facetFunctionSelectors", "offset": 0, "slot": "47", - "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2622_storage)" + "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2723_storage)" }, { - "astId": 2633, + "astId": 2734, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_facetAddresses", "offset": 0, @@ -2226,15 +2226,15 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 2638, + "astId": 2739, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "prime", "offset": 0, "slot": "49", - "type": "t_contract(IPrime)12283" + "type": "t_contract(IPrime)12523" }, { - "astId": 2647, + "astId": 2748, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "isForcedLiquidationEnabledForUser", "offset": 0, @@ -2242,7 +2242,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2652, + "astId": 2753, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "xvs", "offset": 0, @@ -2250,7 +2250,7 @@ "type": "t_address" }, { - "astId": 2654, + "astId": 2755, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "xvsVToken", "offset": 0, @@ -2276,8 +2276,8 @@ "label": "bytes4[]", "numberOfBytes": "32" }, - "t_array(t_contract(VToken)23033)dyn_storage": { - "base": "t_contract(VToken)23033", + "t_array(t_contract(VToken)23484)dyn_storage": { + "base": "t_contract(VToken)23484", "encoding": "dynamic_array", "label": "contract VToken[]", "numberOfBytes": "32" @@ -2292,37 +2292,37 @@ "label": "bytes4", "numberOfBytes": "4" }, - "t_contract(ComptrollerLensInterface)2377": { + "t_contract(ComptrollerLensInterface)2478": { "encoding": "inplace", "label": "contract ComptrollerLensInterface", "numberOfBytes": "20" }, - "t_contract(IPrime)12283": { + "t_contract(IPrime)12523": { "encoding": "inplace", "label": "contract IPrime", "numberOfBytes": "20" }, - "t_contract(PriceOracle)12106": { + "t_contract(PriceOracle)12346": { "encoding": "inplace", "label": "contract PriceOracle", "numberOfBytes": "20" }, - "t_contract(VAIControllerInterface)15582": { + "t_contract(VAIControllerInterface)15644": { "encoding": "inplace", "label": "contract VAIControllerInterface", "numberOfBytes": "20" }, - "t_contract(VToken)23033": { + "t_contract(VToken)23484": { "encoding": "inplace", "label": "contract VToken", "numberOfBytes": "20" }, - "t_mapping(t_address,t_array(t_contract(VToken)23033)dyn_storage)": { + "t_mapping(t_address,t_array(t_contract(VToken)23484)dyn_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => contract VToken[])", "numberOfBytes": "32", - "value": "t_array(t_contract(VToken)23033)dyn_storage" + "value": "t_array(t_contract(VToken)23484)dyn_storage" }, "t_mapping(t_address,t_bool)": { "encoding": "mapping", @@ -2352,26 +2352,26 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_bool)" }, - "t_mapping(t_address,t_struct(FacetFunctionSelectors)2622_storage)": { + "t_mapping(t_address,t_struct(FacetFunctionSelectors)2723_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV13Storage.FacetFunctionSelectors)", "numberOfBytes": "32", - "value": "t_struct(FacetFunctionSelectors)2622_storage" + "value": "t_struct(FacetFunctionSelectors)2723_storage" }, - "t_mapping(t_address,t_struct(Market)2437_storage)": { + "t_mapping(t_address,t_struct(Market)2538_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.Market)", "numberOfBytes": "32", - "value": "t_struct(Market)2437_storage" + "value": "t_struct(Market)2538_storage" }, - "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)": { + "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.VenusMarketState)", "numberOfBytes": "32", - "value": "t_struct(VenusMarketState)2464_storage" + "value": "t_struct(VenusMarketState)2565_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -2380,12 +2380,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2616_storage)": { + "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2717_storage)": { "encoding": "mapping", "key": "t_bytes4", "label": "mapping(bytes4 => struct ComptrollerV13Storage.FacetAddressAndPosition)", "numberOfBytes": "32", - "value": "t_struct(FacetAddressAndPosition)2616_storage" + "value": "t_struct(FacetAddressAndPosition)2717_storage" }, "t_mapping(t_uint256,t_bool)": { "encoding": "mapping", @@ -2394,12 +2394,12 @@ "numberOfBytes": "32", "value": "t_bool" }, - "t_struct(FacetAddressAndPosition)2616_storage": { + "t_struct(FacetAddressAndPosition)2717_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetAddressAndPosition", "members": [ { - "astId": 2613, + "astId": 2714, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "facetAddress", "offset": 0, @@ -2407,7 +2407,7 @@ "type": "t_address" }, { - "astId": 2615, + "astId": 2716, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "functionSelectorPosition", "offset": 20, @@ -2417,12 +2417,12 @@ ], "numberOfBytes": "32" }, - "t_struct(FacetFunctionSelectors)2622_storage": { + "t_struct(FacetFunctionSelectors)2723_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetFunctionSelectors", "members": [ { - "astId": 2619, + "astId": 2720, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "functionSelectors", "offset": 0, @@ -2430,7 +2430,7 @@ "type": "t_array(t_bytes4)dyn_storage" }, { - "astId": 2621, + "astId": 2722, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "facetAddressPosition", "offset": 0, @@ -2440,12 +2440,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Market)2437_storage": { + "t_struct(Market)2538_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.Market", "members": [ { - "astId": 2428, + "astId": 2529, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "isListed", "offset": 0, @@ -2453,7 +2453,7 @@ "type": "t_bool" }, { - "astId": 2430, + "astId": 2531, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "collateralFactorMantissa", "offset": 0, @@ -2461,7 +2461,7 @@ "type": "t_uint256" }, { - "astId": 2434, + "astId": 2535, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "accountMembership", "offset": 0, @@ -2469,7 +2469,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2436, + "astId": 2537, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "isVenus", "offset": 0, @@ -2479,12 +2479,12 @@ ], "numberOfBytes": "128" }, - "t_struct(VenusMarketState)2464_storage": { + "t_struct(VenusMarketState)2565_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.VenusMarketState", "members": [ { - "astId": 2461, + "astId": 2562, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "index", "offset": 0, @@ -2492,7 +2492,7 @@ "type": "t_uint224" }, { - "astId": 2463, + "astId": 2564, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "block", "offset": 28, diff --git a/deployments/bscmainnet/SetterFacet.json b/deployments/bscmainnet/SetterFacet.json index 000c3ebb1..888011bb5 100644 --- a/deployments/bscmainnet/SetterFacet.json +++ b/deployments/bscmainnet/SetterFacet.json @@ -1,5 +1,5 @@ { - "address": "0x7dc9E7b21a9E343f4AD926b8B00Cff5adf5c1CdE", + "address": "0x9B0D9D7c50d90f23449c4BbCAA671Ce7cd19DbCf", "abi": [ { "anonymous": false, @@ -1833,28 +1833,28 @@ "type": "function" } ], - "transactionHash": "0x3d36920a4af6c0a8caa12b5f0b566594e13dceac6d660e5ceb59eaff04ea5b75", + "transactionHash": "0xfa65f873779220407c55bb16d5e885876e54c8dd681217a58d8e4589535a8312", "receipt": { "to": null, - "from": "0x7Bf1Fe2C42E79dbA813Bf5026B7720935a55ec5f", - "contractAddress": "0x7dc9E7b21a9E343f4AD926b8B00Cff5adf5c1CdE", - "transactionIndex": 238, + "from": "0x8BDA9f9E1fEF0DFd404Fef338D9fE4c543d172e1", + "contractAddress": "0x9B0D9D7c50d90f23449c4BbCAA671Ce7cd19DbCf", + "transactionIndex": 132, "gasUsed": "2759641", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf78db40c7201d27922ffa078b92374de37779c332b2f16ef662bfb5293372167", - "transactionHash": "0x3d36920a4af6c0a8caa12b5f0b566594e13dceac6d660e5ceb59eaff04ea5b75", + "blockHash": "0x2c32fc6137314de21c91159360f8489c66d56604944c0e73d5f59267def94d04", + "transactionHash": "0xfa65f873779220407c55bb16d5e885876e54c8dd681217a58d8e4589535a8312", "logs": [], - "blockNumber": 36961173, - "cumulativeGasUsed": "22056943", + "blockNumber": 39374393, + "cumulativeGasUsed": "12912811", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "ad834ffdd224ebe1944f429cc9972360", - "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"pauseState\",\"type\":\"bool\"}],\"name\":\"ActionPausedMarket\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"ActionProtocolPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"IsForcedLiquidationEnabledForUserUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"IsForcedLiquidationEnabledUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlAddress\",\"type\":\"address\"}],\"name\":\"NewAccessControl\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBorrowCap\",\"type\":\"uint256\"}],\"name\":\"NewBorrowCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCloseFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCloseFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCollateralFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCollateralFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldComptrollerLens\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newComptrollerLens\",\"type\":\"address\"}],\"name\":\"NewComptrollerLens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":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\":\"address\",\"name\":\"oldLiquidatorContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLiquidatorContract\",\"type\":\"address\"}],\"name\":\"NewLiquidatorContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldPauseGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPauseGuardian\",\"type\":\"address\"}],\"name\":\"NewPauseGuardian\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract PriceOracle\",\"name\":\"oldPriceOracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract PriceOracle\",\"name\":\"newPriceOracle\",\"type\":\"address\"}],\"name\":\"NewPriceOracle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IPrime\",\"name\":\"oldPrimeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IPrime\",\"name\":\"newPrimeToken\",\"type\":\"address\"}],\"name\":\"NewPrimeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSupplyCap\",\"type\":\"uint256\"}],\"name\":\"NewSupplyCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldTreasuryAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTreasuryAddress\",\"type\":\"address\"}],\"name\":\"NewTreasuryAddress\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldTreasuryGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTreasuryGuardian\",\"type\":\"address\"}],\"name\":\"NewTreasuryGuardian\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldTreasuryPercent\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newTreasuryPercent\",\"type\":\"uint256\"}],\"name\":\"NewTreasuryPercent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VAIControllerInterface\",\"name\":\"oldVAIController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract VAIControllerInterface\",\"name\":\"newVAIController\",\"type\":\"address\"}],\"name\":\"NewVAIController\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVAIMintRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVAIMintRate\",\"type\":\"uint256\"}],\"name\":\"NewVAIMintRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"releaseStartBlock_\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"releaseInterval_\",\"type\":\"uint256\"}],\"name\":\"NewVAIVaultInfo\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVenusVAIVaultRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVenusVAIVaultRate\",\"type\":\"uint256\"}],\"name\":\"NewVenusVAIVaultRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldXVS\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newXVS\",\"type\":\"address\"}],\"name\":\"NewXVSToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldXVSVToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newXVSVToken\",\"type\":\"address\"}],\"name\":\"NewXVSVToken\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAccessControlAddress\",\"type\":\"address\"}],\"name\":\"_setAccessControl\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"markets_\",\"type\":\"address[]\"},{\"internalType\":\"enum ComptrollerTypes.Action[]\",\"name\":\"actions_\",\"type\":\"uint8[]\"},{\"internalType\":\"bool\",\"name\":\"paused_\",\"type\":\"bool\"}],\"name\":\"_setActionsPaused\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"_setCloseFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"_setCollateralFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"comptrollerLens_\",\"type\":\"address\"}],\"name\":\"_setComptrollerLens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"_setForcedLiquidation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"_setForcedLiquidationForUser\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"_setLiquidationIncentive\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newLiquidatorContract_\",\"type\":\"address\"}],\"name\":\"_setLiquidatorContract\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newBorrowCaps\",\"type\":\"uint256[]\"}],\"name\":\"_setMarketBorrowCaps\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newSupplyCaps\",\"type\":\"uint256[]\"}],\"name\":\"_setMarketSupplyCaps\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPauseGuardian\",\"type\":\"address\"}],\"name\":\"_setPauseGuardian\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"_setPriceOracle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"_prime\",\"type\":\"address\"}],\"name\":\"_setPrimeToken\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"_setProtocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newTreasuryGuardian\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newTreasuryAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newTreasuryPercent\",\"type\":\"uint256\"}],\"name\":\"_setTreasuryData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"vaiController_\",\"type\":\"address\"}],\"name\":\"_setVAIController\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newVAIMintRate\",\"type\":\"uint256\"}],\"name\":\"_setVAIMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"releaseStartBlock_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minReleaseAmount_\",\"type\":\"uint256\"}],\"name\":\"_setVAIVaultInfo\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"venusVAIVaultRate_\",\"type\":\"uint256\"}],\"name\":\"_setVenusVAIVaultRate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"xvs_\",\"type\":\"address\"}],\"name\":\"_setXVSToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"xvsVToken_\",\"type\":\"address\"}],\"name\":\"_setXVSVToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setMintedVAIOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the setters for the states\",\"methods\":{\"_setAccessControl(address)\":{\"details\":\"Allows the contract admin to set the address of access control of this contract\",\"params\":{\"newAccessControlAddress\":\"New address for the access control\"},\"return\":\"uint256 0=success, otherwise will revert\"},\"_setActionsPaused(address[],uint8[],bool)\":{\"details\":\"Allows a privileged role to pause/unpause the protocol action state\",\"params\":{\"actions_\":\"List of action ids to pause/unpause\",\"markets_\":\"Markets to pause/unpause the actions on\",\"paused_\":\"The new paused state (true=paused, false=unpaused)\"}},\"_setCloseFactor(uint256)\":{\"details\":\"Allows the contract admin to set the closeFactor used to liquidate borrows\",\"params\":{\"newCloseFactorMantissa\":\"New close factor, scaled by 1e18\"},\"return\":\"uint256 0=success, otherwise will revert\"},\"_setCollateralFactor(address,uint256)\":{\"details\":\"Allows a privileged role to set the collateralFactorMantissa\",\"params\":{\"newCollateralFactorMantissa\":\"The new collateral factor, scaled by 1e18\",\"vToken\":\"The market to set the factor on\"},\"return\":\"uint256 0=success, otherwise a failure. (See ErrorReporter for details)\"},\"_setComptrollerLens(address)\":{\"details\":\"Set ComptrollerLens contract address\",\"params\":{\"comptrollerLens_\":\"The new ComptrollerLens contract address to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setForcedLiquidation(address,bool)\":{\"details\":\"Allows a privileged role to set enable/disable forced liquidations\",\"params\":{\"enable\":\"Whether to enable forced liquidations\",\"vTokenBorrowed\":\"Borrowed vToken\"}},\"_setForcedLiquidationForUser(address,address,bool)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"enable\":\"Whether to enable forced liquidations\",\"vTokenBorrowed\":\"Borrowed vToken\"}},\"_setLiquidationIncentive(uint256)\":{\"details\":\"Allows a privileged role to set the liquidationIncentiveMantissa\",\"params\":{\"newLiquidationIncentiveMantissa\":\"New liquidationIncentive scaled by 1e18\"},\"return\":\"uint256 0=success, otherwise a failure. (See ErrorReporter for details)\"},\"_setLiquidatorContract(address)\":{\"details\":\"Allows the contract admin to update the address of liquidator contract\",\"params\":{\"newLiquidatorContract_\":\"The new address of the liquidator contract\"}},\"_setMarketBorrowCaps(address[],uint256[])\":{\"details\":\"Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to unlimited borrowing\",\"params\":{\"newBorrowCaps\":\"The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing\",\"vTokens\":\"The addresses of the markets (tokens) to change the borrow caps for\"}},\"_setMarketSupplyCaps(address[],uint256[])\":{\"details\":\"Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\",\"params\":{\"newSupplyCaps\":\"The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\",\"vTokens\":\"The addresses of the markets (tokens) to change the supply caps for\"}},\"_setPauseGuardian(address)\":{\"details\":\"Allows the contract admin to change the Pause Guardian\",\"params\":{\"newPauseGuardian\":\"The address of the new Pause Guardian\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"_setPriceOracle(address)\":{\"details\":\"Allows the contract admin to set a new price oracle used by the Comptroller\",\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setPrimeToken(address)\":{\"return\":\"uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setProtocolPaused(bool)\":{\"details\":\"Allows a privileged role to pause/unpause protocol\",\"params\":{\"state\":\"The new state (true=paused, false=unpaused)\"},\"return\":\"bool The updated state of the protocol\"},\"_setTreasuryData(address,address,uint256)\":{\"params\":{\"newTreasuryAddress\":\"The new address of the treasury to be set\",\"newTreasuryGuardian\":\"The new address of the treasury guardian to be set\",\"newTreasuryPercent\":\"The new treasury percent to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIController(address)\":{\"details\":\"Admin function to set a new VAI controller\",\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIMintRate(uint256)\":{\"params\":{\"newVAIMintRate\":\"The new VAI mint rate to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIVaultInfo(address,uint256,uint256)\":{\"params\":{\"minReleaseAmount_\":\"The minimum release amount to VAI Vault\",\"releaseStartBlock_\":\"The start block of release to VAI Vault\",\"vault_\":\"The address of the VAI Vault\"}},\"_setVenusVAIVaultRate(uint256)\":{\"params\":{\"venusVAIVaultRate_\":\"The amount of XVS wei per block to distribute to VAI Vault\"}},\"_setXVSToken(address)\":{\"params\":{\"xvs_\":\"The address of the XVS token\"}},\"_setXVSVToken(address)\":{\"params\":{\"xvsVToken_\":\"The address of the XVS vToken\"}},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"setMintedVAIOf(address,uint256)\":{\"params\":{\"amount\":\"The amount of VAI to set to the account\",\"owner\":\"The address of the account to set\"},\"return\":\"The number of minted VAI by `owner`\"}},\"title\":\"SetterFacet\"},\"userdoc\":{\"methods\":{\"_setAccessControl(address)\":{\"notice\":\"Sets the address of the access control of this contract\"},\"_setActionsPaused(address[],uint8[],bool)\":{\"notice\":\"Pause/unpause certain actions\"},\"_setCloseFactor(uint256)\":{\"notice\":\"Sets the closeFactor used when liquidating borrows\"},\"_setCollateralFactor(address,uint256)\":{\"notice\":\"Sets the collateralFactor for a market\"},\"_setForcedLiquidation(address,bool)\":{\"notice\":\"Enables forced liquidations for a market. If forced liquidation is enabled, borrows in the market may be liquidated regardless of the account liquidity\"},\"_setForcedLiquidationForUser(address,address,bool)\":{\"notice\":\"Enables forced liquidations for user's borrows in a certain market. If forced liquidation is enabled, user's borrows in the market may be liquidated regardless of the account liquidity. Forced liquidation may be enabled for a user even if it is not enabled for the entire market.\"},\"_setLiquidationIncentive(uint256)\":{\"notice\":\"Sets liquidationIncentive\"},\"_setLiquidatorContract(address)\":{\"notice\":\"Update the address of the liquidator contract\"},\"_setMarketBorrowCaps(address[],uint256[])\":{\"notice\":\"Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\"},\"_setMarketSupplyCaps(address[],uint256[])\":{\"notice\":\"Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\"},\"_setPauseGuardian(address)\":{\"notice\":\"Admin function to change the Pause Guardian\"},\"_setPriceOracle(address)\":{\"notice\":\"Sets a new price oracle for the comptroller\"},\"_setPrimeToken(address)\":{\"notice\":\"Sets the prime token contract for the comptroller\"},\"_setProtocolPaused(bool)\":{\"notice\":\"Set whole protocol pause/unpause state\"},\"_setTreasuryData(address,address,uint256)\":{\"notice\":\"Set the treasury data.\"},\"_setVAIController(address)\":{\"notice\":\"Sets a new VAI controller\"},\"_setVAIMintRate(uint256)\":{\"notice\":\"Set the VAI mint rate\"},\"_setVAIVaultInfo(address,uint256,uint256)\":{\"notice\":\"Set the VAI Vault infos\"},\"_setVenusVAIVaultRate(uint256)\":{\"notice\":\"Set the amount of XVS distributed per block to VAI Vault\"},\"_setXVSToken(address)\":{\"notice\":\"Set the address of the XVS token\"},\"_setXVSVToken(address)\":{\"notice\":\"Set the address of the XVS vToken\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"setMintedVAIOf(address,uint256)\":{\"notice\":\"Set the minted VAI amount of the `owner`\"}},\"notice\":\"This facet contract contains all the configurational setter functions\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/SetterFacet.sol\":\"SetterFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which corresponds to unlimited borrowing.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x13aa5a019c0ea5149d00480b5a3e1281ec316f8d159c52705f45b4c75a5abcb8\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/SetterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { ISetterFacet } from \\\"../interfaces/ISetterFacet.sol\\\";\\nimport { PriceOracle } from \\\"../../../Oracle/PriceOracle.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"../../ComptrollerLensInterface.sol\\\";\\nimport { VAIControllerInterface } from \\\"../../../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\nimport { IPrime } from \\\"../../../Tokens/Prime/IPrime.sol\\\";\\n\\n/**\\n * @title SetterFacet\\n * @author Venus\\n * @dev This facet contains all the setters for the states\\n * @notice This facet contract contains all the configurational setter functions\\n */\\ncontract SetterFacet is ISetterFacet, FacetBase {\\n /// @notice Emitted when close factor is changed by admin\\n event NewCloseFactor(uint256 oldCloseFactorMantissa, uint256 newCloseFactorMantissa);\\n\\n /// @notice Emitted when a collateral factor is changed by admin\\n event NewCollateralFactor(\\n VToken indexed vToken,\\n uint256 oldCollateralFactorMantissa,\\n uint256 newCollateralFactorMantissa\\n );\\n\\n /// @notice Emitted when liquidation incentive is changed by admin\\n event NewLiquidationIncentive(uint256 oldLiquidationIncentiveMantissa, uint256 newLiquidationIncentiveMantissa);\\n\\n /// @notice Emitted when price oracle is changed\\n event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle);\\n\\n /// @notice Emitted when borrow cap for a vToken is changed\\n event NewBorrowCap(VToken indexed vToken, uint256 newBorrowCap);\\n\\n /// @notice Emitted when VAIController is changed\\n event NewVAIController(VAIControllerInterface oldVAIController, VAIControllerInterface newVAIController);\\n\\n /// @notice Emitted when VAI mint rate is changed by admin\\n event NewVAIMintRate(uint256 oldVAIMintRate, uint256 newVAIMintRate);\\n\\n /// @notice Emitted when protocol state is changed by admin\\n event ActionProtocolPaused(bool state);\\n\\n /// @notice Emitted when treasury guardian is changed\\n event NewTreasuryGuardian(address oldTreasuryGuardian, address newTreasuryGuardian);\\n\\n /// @notice Emitted when treasury address is changed\\n event NewTreasuryAddress(address oldTreasuryAddress, address newTreasuryAddress);\\n\\n /// @notice Emitted when treasury percent is changed\\n event NewTreasuryPercent(uint256 oldTreasuryPercent, uint256 newTreasuryPercent);\\n\\n /// @notice Emitted when liquidator adress is changed\\n event NewLiquidatorContract(address oldLiquidatorContract, address newLiquidatorContract);\\n\\n /// @notice Emitted when ComptrollerLens address is changed\\n event NewComptrollerLens(address oldComptrollerLens, address newComptrollerLens);\\n\\n /// @notice Emitted when supply cap for a vToken is changed\\n event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /// @notice Emitted when pause guardian is changed\\n event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken indexed vToken, Action indexed action, bool pauseState);\\n\\n /// @notice Emitted when VAI Vault info is changed\\n event NewVAIVaultInfo(address indexed vault_, uint256 releaseStartBlock_, uint256 releaseInterval_);\\n\\n /// @notice Emitted when Venus VAI Vault rate is changed\\n event NewVenusVAIVaultRate(uint256 oldVenusVAIVaultRate, uint256 newVenusVAIVaultRate);\\n\\n /// @notice Emitted when prime token contract address is changed\\n event NewPrimeToken(IPrime oldPrimeToken, IPrime newPrimeToken);\\n\\n /// @notice Emitted when forced liquidation is enabled or disabled for all users in a market\\n event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);\\n\\n /// @notice Emitted when forced liquidation is enabled or disabled for a user borrowing in a market\\n event IsForcedLiquidationEnabledForUserUpdated(address indexed borrower, address indexed vToken, bool enable);\\n\\n /// @notice Emitted when XVS token address is changed\\n event NewXVSToken(address indexed oldXVS, address indexed newXVS);\\n\\n /// @notice Emitted when XVS vToken address is changed\\n event NewXVSVToken(address indexed oldXVSVToken, address indexed newXVSVToken);\\n\\n /**\\n * @notice Compare two addresses to ensure they are different\\n * @param oldAddress The original address to compare\\n * @param newAddress The new address to compare\\n */\\n modifier compareAddress(address oldAddress, address newAddress) {\\n require(oldAddress != newAddress, \\\"old address is same as new address\\\");\\n _;\\n }\\n\\n /**\\n * @notice Compare two values to ensure they are different\\n * @param oldValue The original value to compare\\n * @param newValue The new value to compare\\n */\\n modifier compareValue(uint256 oldValue, uint256 newValue) {\\n require(oldValue != newValue, \\\"old value is same as new value\\\");\\n _;\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the comptroller\\n * @dev Allows the contract admin to set a new price oracle used by the Comptroller\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setPriceOracle(\\n PriceOracle newOracle\\n ) external compareAddress(address(oracle), address(newOracle)) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(address(newOracle));\\n\\n // Track the old oracle for the comptroller\\n PriceOracle oldOracle = oracle;\\n\\n // Set comptroller's oracle to newOracle\\n oracle = newOracle;\\n\\n // Emit NewPriceOracle(oldOracle, newOracle)\\n emit NewPriceOracle(oldOracle, newOracle);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the closeFactor used when liquidating borrows\\n * @dev Allows the contract admin to set the closeFactor used to liquidate borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @return uint256 0=success, otherwise will revert\\n */\\n function _setCloseFactor(\\n uint256 newCloseFactorMantissa\\n ) external compareValue(closeFactorMantissa, newCloseFactorMantissa) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n\\n Exp memory newCloseFactorExp = Exp({ mantissa: newCloseFactorMantissa });\\n\\n //-- Check close factor <= 0.9\\n Exp memory highLimit = Exp({ mantissa: closeFactorMaxMantissa });\\n //-- Check close factor >= 0.05\\n Exp memory lowLimit = Exp({ mantissa: closeFactorMinMantissa });\\n\\n if (lessThanExp(highLimit, newCloseFactorExp) || greaterThanExp(lowLimit, newCloseFactorExp)) {\\n return fail(Error.INVALID_CLOSE_FACTOR, FailureInfo.SET_CLOSE_FACTOR_VALIDATION);\\n }\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the address of the access control of this contract\\n * @dev Allows the contract admin to set the address of access control of this contract\\n * @param newAccessControlAddress New address for the access control\\n * @return uint256 0=success, otherwise will revert\\n */\\n function _setAccessControl(\\n address newAccessControlAddress\\n ) external compareAddress(accessControl, newAccessControlAddress) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(newAccessControlAddress);\\n\\n address oldAccessControlAddress = accessControl;\\n\\n accessControl = newAccessControlAddress;\\n emit NewAccessControl(oldAccessControlAddress, newAccessControlAddress);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev Allows a privileged role to set the collateralFactorMantissa\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\\n */\\n function _setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa\\n )\\n external\\n compareValue(markets[address(vToken)].collateralFactorMantissa, newCollateralFactorMantissa)\\n returns (uint256)\\n {\\n // Check caller is allowed by access control manager\\n ensureAllowed(\\\"_setCollateralFactor(address,uint256)\\\");\\n ensureNonzeroAddress(address(vToken));\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n ensureListed(market);\\n\\n Exp memory newCollateralFactorExp = Exp({ mantissa: newCollateralFactorMantissa });\\n\\n //-- Check collateral factor <= 0.9\\n Exp memory highLimit = Exp({ mantissa: collateralFactorMaxMantissa });\\n if (lessThanExp(highLimit, newCollateralFactorExp)) {\\n return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION);\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(vToken) == 0) {\\n return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE);\\n }\\n\\n // Set market's collateral factor to new collateral factor, remember old value\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n\\n // Emit event with asset, old collateral factor, and new collateral factor\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev Allows a privileged role to set the liquidationIncentiveMantissa\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\\n */\\n function _setLiquidationIncentive(\\n uint256 newLiquidationIncentiveMantissa\\n ) external compareValue(liquidationIncentiveMantissa, newLiquidationIncentiveMantissa) returns (uint256) {\\n ensureAllowed(\\\"_setLiquidationIncentive(uint256)\\\");\\n\\n require(newLiquidationIncentiveMantissa >= 1e18, \\\"incentive < 1e18\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n // Set liquidation incentive to new incentive\\n liquidationIncentiveMantissa = newLiquidationIncentiveMantissa;\\n\\n // Emit event with old incentive, new incentive\\n emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Update the address of the liquidator contract\\n * @dev Allows the contract admin to update the address of liquidator contract\\n * @param newLiquidatorContract_ The new address of the liquidator contract\\n */\\n function _setLiquidatorContract(\\n address newLiquidatorContract_\\n ) external compareAddress(liquidatorContract, newLiquidatorContract_) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(newLiquidatorContract_);\\n address oldLiquidatorContract = liquidatorContract;\\n liquidatorContract = newLiquidatorContract_;\\n emit NewLiquidatorContract(oldLiquidatorContract, newLiquidatorContract_);\\n }\\n\\n /**\\n * @notice Admin function to change the Pause Guardian\\n * @dev Allows the contract admin to change the Pause Guardian\\n * @param newPauseGuardian The address of the new Pause Guardian\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function _setPauseGuardian(\\n address newPauseGuardian\\n ) external compareAddress(pauseGuardian, newPauseGuardian) returns (uint256) {\\n ensureAdmin();\\n ensureNonzeroAddress(newPauseGuardian);\\n\\n // Save current value for inclusion in log\\n address oldPauseGuardian = pauseGuardian;\\n // Store pauseGuardian with value newPauseGuardian\\n pauseGuardian = newPauseGuardian;\\n\\n // Emit NewPauseGuardian(OldPauseGuardian, NewPauseGuardian)\\n emit NewPauseGuardian(oldPauseGuardian, newPauseGuardian);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\\n * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to unlimited borrowing\\n * @param vTokens The addresses of the markets (tokens) to change the borrow caps for\\n * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing\\n */\\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n ensureAllowed(\\\"_setMarketBorrowCaps(address[],uint256[])\\\");\\n\\n uint256 numMarkets = vTokens.length;\\n uint256 numBorrowCaps = newBorrowCaps.length;\\n\\n require(numMarkets != 0 && numMarkets == numBorrowCaps, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numMarkets; ++i) {\\n borrowCaps[address(vTokens[i])] = newBorrowCaps[i];\\n emit NewBorrowCap(vTokens[i], newBorrowCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\\n * @dev Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\\n * @param vTokens The addresses of the markets (tokens) to change the supply caps for\\n * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\\n */\\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n ensureAllowed(\\\"_setMarketSupplyCaps(address[],uint256[])\\\");\\n\\n uint256 numMarkets = vTokens.length;\\n uint256 numSupplyCaps = newSupplyCaps.length;\\n\\n require(numMarkets != 0 && numMarkets == numSupplyCaps, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numMarkets; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Set whole protocol pause/unpause state\\n * @dev Allows a privileged role to pause/unpause protocol\\n * @param state The new state (true=paused, false=unpaused)\\n * @return bool The updated state of the protocol\\n */\\n function _setProtocolPaused(bool state) external returns (bool) {\\n ensureAllowed(\\\"_setProtocolPaused(bool)\\\");\\n\\n protocolPaused = state;\\n emit ActionProtocolPaused(state);\\n return state;\\n }\\n\\n /**\\n * @notice Pause/unpause certain actions\\n * @dev Allows a privileged role to pause/unpause the protocol action state\\n * @param markets_ Markets to pause/unpause the actions on\\n * @param actions_ List of action ids to pause/unpause\\n * @param paused_ The new paused state (true=paused, false=unpaused)\\n */\\n function _setActionsPaused(address[] calldata markets_, Action[] calldata actions_, bool paused_) external {\\n ensureAllowed(\\\"_setActionsPaused(address[],uint8[],bool)\\\");\\n\\n uint256 numMarkets = markets_.length;\\n uint256 numActions = actions_.length;\\n for (uint256 marketIdx; marketIdx < numMarkets; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < numActions; ++actionIdx) {\\n setActionPausedInternal(markets_[marketIdx], actions_[actionIdx], paused_);\\n }\\n }\\n }\\n\\n /**\\n * @dev Pause/unpause an action on a market\\n * @param market Market to pause/unpause the action on\\n * @param action Action id to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n */\\n function setActionPausedInternal(address market, Action action, bool paused) internal {\\n ensureListed(markets[market]);\\n _actionPaused[market][uint256(action)] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @notice Sets a new VAI controller\\n * @dev Admin function to set a new VAI controller\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setVAIController(\\n VAIControllerInterface vaiController_\\n ) external compareAddress(address(vaiController), address(vaiController_)) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(address(vaiController_));\\n\\n VAIControllerInterface oldVaiController = vaiController;\\n vaiController = vaiController_;\\n emit NewVAIController(oldVaiController, vaiController_);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the VAI mint rate\\n * @param newVAIMintRate The new VAI mint rate to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setVAIMintRate(\\n uint256 newVAIMintRate\\n ) external compareValue(vaiMintRate, newVAIMintRate) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n uint256 oldVAIMintRate = vaiMintRate;\\n vaiMintRate = newVAIMintRate;\\n emit NewVAIMintRate(oldVAIMintRate, newVAIMintRate);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the minted VAI amount of the `owner`\\n * @param owner The address of the account to set\\n * @param amount The amount of VAI to set to the account\\n * @return The number of minted VAI by `owner`\\n */\\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256) {\\n checkProtocolPauseState();\\n\\n // Pausing is a very serious situation - we revert to sound the alarms\\n require(!mintVAIGuardianPaused && !repayVAIGuardianPaused, \\\"VAI is paused\\\");\\n // Check caller is vaiController\\n if (msg.sender != address(vaiController)) {\\n return fail(Error.REJECTION, FailureInfo.SET_MINTED_VAI_REJECTION);\\n }\\n mintedVAIs[owner] = amount;\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the treasury data.\\n * @param newTreasuryGuardian The new address of the treasury guardian to be set\\n * @param newTreasuryAddress The new address of the treasury to be set\\n * @param newTreasuryPercent The new treasury percent to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setTreasuryData(\\n address newTreasuryGuardian,\\n address newTreasuryAddress,\\n uint256 newTreasuryPercent\\n ) external returns (uint256) {\\n // Check caller is admin\\n ensureAdminOr(treasuryGuardian);\\n\\n require(newTreasuryPercent < 1e18, \\\"percent >= 100%\\\");\\n ensureNonzeroAddress(newTreasuryGuardian);\\n ensureNonzeroAddress(newTreasuryAddress);\\n\\n address oldTreasuryGuardian = treasuryGuardian;\\n address oldTreasuryAddress = treasuryAddress;\\n uint256 oldTreasuryPercent = treasuryPercent;\\n\\n treasuryGuardian = newTreasuryGuardian;\\n treasuryAddress = newTreasuryAddress;\\n treasuryPercent = newTreasuryPercent;\\n\\n emit NewTreasuryGuardian(oldTreasuryGuardian, newTreasuryGuardian);\\n emit NewTreasuryAddress(oldTreasuryAddress, newTreasuryAddress);\\n emit NewTreasuryPercent(oldTreasuryPercent, newTreasuryPercent);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /*** Venus Distribution ***/\\n\\n /**\\n * @dev Set ComptrollerLens contract address\\n * @param comptrollerLens_ The new ComptrollerLens contract address to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setComptrollerLens(\\n ComptrollerLensInterface comptrollerLens_\\n ) external compareAddress(address(comptrollerLens), address(comptrollerLens_)) returns (uint256) {\\n ensureAdmin();\\n ensureNonzeroAddress(address(comptrollerLens_));\\n address oldComptrollerLens = address(comptrollerLens);\\n comptrollerLens = comptrollerLens_;\\n emit NewComptrollerLens(oldComptrollerLens, address(comptrollerLens));\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the amount of XVS distributed per block to VAI Vault\\n * @param venusVAIVaultRate_ The amount of XVS wei per block to distribute to VAI Vault\\n */\\n function _setVenusVAIVaultRate(\\n uint256 venusVAIVaultRate_\\n ) external compareValue(venusVAIVaultRate, venusVAIVaultRate_) {\\n ensureAdmin();\\n if (vaiVaultAddress != address(0)) {\\n releaseToVault();\\n }\\n uint256 oldVenusVAIVaultRate = venusVAIVaultRate;\\n venusVAIVaultRate = venusVAIVaultRate_;\\n emit NewVenusVAIVaultRate(oldVenusVAIVaultRate, venusVAIVaultRate_);\\n }\\n\\n /**\\n * @notice Set the VAI Vault infos\\n * @param vault_ The address of the VAI Vault\\n * @param releaseStartBlock_ The start block of release to VAI Vault\\n * @param minReleaseAmount_ The minimum release amount to VAI Vault\\n */\\n function _setVAIVaultInfo(\\n address vault_,\\n uint256 releaseStartBlock_,\\n uint256 minReleaseAmount_\\n ) external compareAddress(vaiVaultAddress, vault_) {\\n ensureAdmin();\\n ensureNonzeroAddress(vault_);\\n if (vaiVaultAddress != address(0)) {\\n releaseToVault();\\n }\\n\\n vaiVaultAddress = vault_;\\n releaseStartBlock = releaseStartBlock_;\\n minReleaseAmount = minReleaseAmount_;\\n emit NewVAIVaultInfo(vault_, releaseStartBlock_, minReleaseAmount_);\\n }\\n\\n /**\\n * @notice Sets the prime token contract for the comptroller\\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setPrimeToken(IPrime _prime) external returns (uint) {\\n ensureAdmin();\\n ensureNonzeroAddress(address(_prime));\\n\\n IPrime oldPrime = prime;\\n prime = _prime;\\n emit NewPrimeToken(oldPrime, _prime);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /** @notice Enables forced liquidations for a market. If forced liquidation is enabled,\\n * borrows in the market may be liquidated regardless of the account liquidity\\n * @dev Allows a privileged role to set enable/disable forced liquidations\\n * @param vTokenBorrowed Borrowed vToken\\n * @param enable Whether to enable forced liquidations\\n */\\n function _setForcedLiquidation(address vTokenBorrowed, bool enable) external {\\n ensureAllowed(\\\"_setForcedLiquidation(address,bool)\\\");\\n if (vTokenBorrowed != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n isForcedLiquidationEnabled[vTokenBorrowed] = enable;\\n emit IsForcedLiquidationEnabledUpdated(vTokenBorrowed, enable);\\n }\\n\\n /**\\n * @notice Enables forced liquidations for user's borrows in a certain market. If forced\\n * liquidation is enabled, user's borrows in the market may be liquidated regardless of\\n * the account liquidity. Forced liquidation may be enabled for a user even if it is not\\n * enabled for the entire market.\\n * @param borrower The address of the borrower\\n * @param vTokenBorrowed Borrowed vToken\\n * @param enable Whether to enable forced liquidations\\n */\\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external {\\n ensureAllowed(\\\"_setForcedLiquidationForUser(address,address,bool)\\\");\\n if (vTokenBorrowed != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed] = enable;\\n emit IsForcedLiquidationEnabledForUserUpdated(borrower, vTokenBorrowed, enable);\\n }\\n\\n /**\\n * @notice Set the address of the XVS token\\n * @param xvs_ The address of the XVS token\\n */\\n function _setXVSToken(address xvs_) external {\\n ensureAdmin();\\n ensureNonzeroAddress(xvs_);\\n\\n emit NewXVSToken(xvs, xvs_);\\n xvs = xvs_;\\n }\\n\\n /**\\n * @notice Set the address of the XVS vToken\\n * @param xvsVToken_ The address of the XVS vToken\\n */\\n function _setXVSVToken(address xvsVToken_) external {\\n ensureAdmin();\\n ensureNonzeroAddress(xvsVToken_);\\n\\n address underlying = VToken(xvsVToken_).underlying();\\n require(underlying == xvs, \\\"invalid xvs vtoken address\\\");\\n\\n emit NewXVSVToken(xvsVToken, xvsVToken_);\\n xvsVToken = xvsVToken_;\\n }\\n}\\n\",\"keccak256\":\"0x54e751d7dfd92147b1793379714f893759346f8ece01a03d91b1990fae1470b0\"},\"contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { PriceOracle } from \\\"../../../Oracle/PriceOracle.sol\\\";\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { ComptrollerTypes } from \\\"../../ComptrollerStorage.sol\\\";\\nimport { VAIControllerInterface } from \\\"../../../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"../../../Comptroller/ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../../../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ISetterFacet {\\n function _setPriceOracle(PriceOracle newOracle) external returns (uint256);\\n\\n function _setCloseFactor(uint256 newCloseFactorMantissa) external returns (uint256);\\n\\n function _setAccessControl(address newAccessControlAddress) external returns (uint256);\\n\\n function _setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256);\\n\\n function _setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256);\\n\\n function _setLiquidatorContract(address newLiquidatorContract_) external;\\n\\n function _setPauseGuardian(address newPauseGuardian) external returns (uint256);\\n\\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external;\\n\\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external;\\n\\n function _setProtocolPaused(bool state) external returns (bool);\\n\\n function _setActionsPaused(\\n address[] calldata markets,\\n ComptrollerTypes.Action[] calldata actions,\\n bool paused\\n ) external;\\n\\n function _setVAIController(VAIControllerInterface vaiController_) external returns (uint256);\\n\\n function _setVAIMintRate(uint256 newVAIMintRate) external returns (uint256);\\n\\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256);\\n\\n function _setTreasuryData(\\n address newTreasuryGuardian,\\n address newTreasuryAddress,\\n uint256 newTreasuryPercent\\n ) external returns (uint256);\\n\\n function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint256);\\n\\n function _setVenusVAIVaultRate(uint256 venusVAIVaultRate_) external;\\n\\n function _setVAIVaultInfo(address vault_, uint256 releaseStartBlock_, uint256 minReleaseAmount_) external;\\n\\n function _setForcedLiquidation(address vToken, bool enable) external;\\n\\n function _setPrimeToken(IPrime _prime) external returns (uint);\\n\\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external;\\n\\n function _setXVSToken(address xvs_) external;\\n\\n function _setXVSVToken(address xvsVToken_) external;\\n}\\n\",\"keccak256\":\"0x8d1e48445f80aca8652555a50783e3fb908351040abf45a90f1ce557abcabede\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function getVAIAddress() public view returns (address);\\n\\n function getMintableVAI(address minter) public view returns (uint, uint);\\n\\n function mintVAI(address minter, uint mintVAIAmount) external returns (uint);\\n\\n function repayVAI(address repayer, uint repayVAIAmount) external returns (uint);\\n\\n function liquidateVAI(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint, uint);\\n\\n function _initializeVenusVAIState(uint blockNumber) external returns (uint);\\n\\n function updateVenusVAIMintIndex() external returns (uint);\\n\\n function calcDistributeVAIMinterVenus(address vaiMinter) external returns (uint, uint, uint, uint);\\n\\n function getVAIRepayAmount(address account) public view returns (uint);\\n}\\n\",\"keccak256\":\"0x17eb6edb1262c4effcad86f614ff20d00256278485054b11aa5cf011ff6f8a86\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0xc77c4dd91f93f778c5048fa0e68cc0cad2fd4a308add54f0172c507858ce06c8\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506130ee806100206000396000f3fe608060405234801561001057600080fd5b50600436106103f15760003560e01c80637dc0d1d011610215578063bf32442d11610125578063e37d4b79116100b8578063f445d70311610087578063f445d70314610cdf578063f519fc3014610d0d578063f851a44014610d33578063fa6331d814610d3b578063fd51a3ad14610d43576103f1565b8063e37d4b7914610c56578063e4028eee14610c7c578063e85a296014610ca8578063e875544614610cd7576103f1565b8063d24febad116100f4578063d24febad14610be4578063d3270f9914610c1a578063dce1544914610c22578063dcfbc0c714610c4e576103f1565b8063bf32442d14610ba8578063c5b4db5514610bb0578063c5f956af14610bd4578063c7ee005e14610bdc576103f1565b80639bb27d62116101a8578063b8324c7c11610177578063b8324c7c14610afe578063bb82aa5e14610b4c578063bb85745014610b54578063bbb8864a14610b7a578063bec04f7214610ba0576103f1565b80639bb27d6214610aa25780639bf34cbb14610aaa5780639cfdd9e614610ad0578063b2eafc3914610af6576103f1565b8063919a3736116101e4578063919a373614610a465780639254f5e514610a6c5780639460c8b514610a7457806394b2294b14610a9a576103f1565b80637dc0d1d0146109aa5780638a7dc165146109b25780638c1ac18a146109d85780638e8f294b146109fe576103f1565b8063425fad581161031057806352d84d1e116102a3578063607ef6c111610272578063607ef6c1146108b75780636662c7c914610975578063719f701b14610992578063765513831461099a5780637d172bd5146109a2576103f1565b806352d84d1e1461082857806355ee1fe1146108455780635dd3fc9d1461086b5780635f5af1aa14610891576103f1565b80634ef233fc116102df5780634ef233fc146106f95780634fd42e171461071f57806351a485e41461073c578063522c656b146107fa576103f1565b8063425fad58146106915780634a584432146106995780634ada90af146106bf5780634e0853db146106c7576103f1565b806326782247116103885780632ec04124116103575780632ec0412414610621578063317b0b771461063e5780634088c73e1461065b57806341a18d2c14610663576103f1565b806326782247146105145780632a6a60651461051c5780632b5d790c1461053b5780632bc7e29e146105fb576103f1565b806310b98338116103c457806310b983381461046c57806317db2163146104ae57806321af4569146104e857806324a3d6221461050c576103f1565b806302c3bcbb146103f657806304ef9d581461042e57806308e0225c146104365780630db4b4e514610464575b600080fd5b61041c6004803603602081101561040c57600080fd5b50356001600160a01b0316610d6f565b60408051918252519081900360200190f35b61041c610d81565b61041c6004803603604081101561044c57600080fd5b506001600160a01b0381358116916020013516610d87565b61041c610da4565b61049a6004803603604081101561048257600080fd5b506001600160a01b0381358116916020013516610daa565b604080519115158252519081900360200190f35b6104e6600480360360608110156104c457600080fd5b506001600160a01b038135811691602081013590911690604001351515610dca565b005b6104f0610e8f565b604080516001600160a01b039092168252519081900360200190f35b6104f0610e9e565b6104f0610ead565b61049a6004803603602081101561053257600080fd5b50351515610ebc565b6104e66004803603606081101561055157600080fd5b810190602081018135600160201b81111561056b57600080fd5b82018360208201111561057d57600080fd5b803590602001918460208302840111600160201b8311171561059e57600080fd5b919390929091602081019035600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460208302840111600160201b831117156105ee57600080fd5b9193509150351515610f4e565b61041c6004803603602081101561061157600080fd5b50356001600160a01b0316610fea565b61041c6004803603602081101561063757600080fd5b5035610ffc565b61041c6004803603602081101561065457600080fd5b503561109e565b61049a6111c8565b61041c6004803603604081101561067957600080fd5b506001600160a01b03813581169160200135166111d1565b61049a6111ee565b61041c600480360360208110156106af57600080fd5b50356001600160a01b03166111fd565b61041c61120f565b6104e6600480360360608110156106dd57600080fd5b506001600160a01b038135169060208101359060400135611215565b6104e66004803603602081101561070f57600080fd5b50356001600160a01b03166112fa565b61041c6004803603602081101561073557600080fd5b5035611434565b6104e66004803603604081101561075257600080fd5b810190602081018135600160201b81111561076c57600080fd5b82018360208201111561077e57600080fd5b803590602001918460208302840111600160201b8311171561079f57600080fd5b919390929091602081019035600160201b8111156107bc57600080fd5b8201836020820111156107ce57600080fd5b803590602001918460208302840111600160201b831117156107ef57600080fd5b509092509050611538565b6104e66004803603604081101561081057600080fd5b506001600160a01b038135169060200135151561168b565b6104f06004803603602081101561083e57600080fd5b5035611742565b61041c6004803603602081101561085b57600080fd5b50356001600160a01b0316611769565b61041c6004803603602081101561088157600080fd5b50356001600160a01b0316611834565b61041c600480360360208110156108a757600080fd5b50356001600160a01b0316611846565b6104e6600480360360408110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460208302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460208302840111600160201b8311171561096a57600080fd5b509092509050611911565b6104e66004803603602081101561098b57600080fd5b5035611a5b565b61041c611b0c565b61049a611b12565b6104f0611b20565b6104f0611b2f565b61041c600480360360208110156109c857600080fd5b50356001600160a01b0316611b3e565b61049a600480360360208110156109ee57600080fd5b50356001600160a01b0316611b50565b610a2460048036036020811015610a1457600080fd5b50356001600160a01b0316611b65565b6040805193151584526020840192909252151582820152519081900360600190f35b6104e660048036036020811015610a5c57600080fd5b50356001600160a01b0316611b8b565b6104f0611bf8565b61041c60048036036020811015610a8a57600080fd5b50356001600160a01b0316611c07565b61041c611c82565b6104f0611c88565b61041c60048036036020811015610ac057600080fd5b50356001600160a01b0316611c97565b61041c60048036036020811015610ae657600080fd5b50356001600160a01b0316611d61565b6104f0611e2c565b610b2460048036036020811015610b1457600080fd5b50356001600160a01b0316611e3b565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104f0611e65565b6104e660048036036020811015610b6a57600080fd5b50356001600160a01b0316611e74565b61041c60048036036020811015610b9057600080fd5b50356001600160a01b0316611f3b565b61041c611f4d565b6104f0611f53565b610bb8611f62565b604080516001600160e01b039092168252519081900360200190f35b6104f0611f75565b6104f0611f84565b61041c60048036036060811015610bfa57600080fd5b506001600160a01b03813581169160208101359091169060400135611f93565b6104f0612112565b6104f060048036036040811015610c3857600080fd5b506001600160a01b038135169060200135612121565b6104f0612156565b610b2460048036036020811015610c6c57600080fd5b50356001600160a01b0316612165565b61041c60048036036040811015610c9257600080fd5b506001600160a01b03813516906020013561218f565b61049a60048036036040811015610cbe57600080fd5b5080356001600160a01b0316906020013560ff1661238d565b61041c6123cf565b61049a60048036036040811015610cf557600080fd5b506001600160a01b03813581169160200135166123d5565b61041c60048036036020811015610d2357600080fd5b50356001600160a01b03166123f5565b6104f06124c0565b61041c6124cf565b61041c60048036036040811015610d5957600080fd5b506001600160a01b0381351690602001356124d5565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b610deb604051806060016040528060328152602001612f3860329139612582565b6015546001600160a01b03838116911614610e21576001600160a01b0382166000908152600960205260409020610e21906126a6565b6001600160a01b03838116600081815260326020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fc080966e9e93529edc1b244180c245bc60f3d86f1e690a17651a5e428746a8cd9281900390910190a3505050565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b6000610efc6040518060400160405280601881526020017f5f73657450726f746f636f6c50617573656428626f6f6c290000000000000000815250612582565b6018805483151562010000810262ff0000199092169190911790915560408051918252517fd7500633dd3ddd74daa7af62f8c8404c7fe4a81da179998db851696bed004b389181900360200190a15090565b610f6f604051806060016040528060298152602001612f9460299139612582565b838260005b82811015610fe05760005b82811015610fd757610fcf898984818110610f9657fe5b905060200201356001600160a01b0316888884818110610fb257fe5b90506020020135600881118015610fc857600080fd5b50876126f0565b600101610f7f565b50600101610f74565b5050505050505050565b60166020526000908152604090205481565b60006017548280821415611045576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61104d6127a8565b6017805490859055604080518281526020810187905281517f73747d68b346dce1e932bcd238282e7ac84c01569e1f8d0469c222fdc6e9d5a4929181900390910190a160005b9350505b5050919050565b600060055482808214156110e7576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b6110ef6127a8565b6110f7612f24565b50604080516020810190915284815261110e612f24565b506040805160208101909152670c7d713b49da0000815261112d612f24565b50604080516020810190915266b1a2bc2ec50000815261114d82846127fa565b8061115d575061115d8184612801565b156111775761116d600580612808565b9550505050611097565b600580549088905560408051828152602081018a905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a1600098975050505050505050565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b601b546001600160a01b0390811690849081168214156112665760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b61126e6127a8565b6112778561286e565b601b546001600160a01b031615611290576112906128c1565b601b80546001600160a01b0319166001600160a01b038716908117909155601c859055601d849055604080518681526020810186905281517f7059037d74ee16b0fb06a4a30f3348dd2635f301f92e373c92899a25a522ef6e929181900390910190a25050505050565b6113026127a8565b61130b8161286e565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b50516033549091506001600160a01b038083169116146113d7576040805162461bcd60e51b815260206004820152601a60248201527f696e76616c6964207876732076746f6b656e2061646472657373000000000000604482015290519081900360640190fd5b6034546040516001600160a01b038085169216907f2565e1579c0926afb7113edbfd85373e85cadaa3e0346f04de19686a2bb86ed190600090a350603480546001600160a01b0319166001600160a01b0392909216919091179055565b6000600654828082141561147d576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61149e604051806060016040528060218152602001612fbd60219139612582565b670de0b6b3a76400008410156114ee576040805162461bcd60e51b815260206004820152601060248201526f0d2dcc6cadce8d2ecca40784062ca62760831b604482015290519081900360640190fd5b6006805490859055604080518281526020810187905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611093565b611559604051806060016040528060298152602001612fde60299139612582565b8281811580159061156957508082145b6115aa576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b82811015611682578484828181106115c157fe5b90506020020135602760008989858181106115d857fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000208190555086868281811061161857fe5b905060200201356001600160a01b03166001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f886868481811061165e57fe5b905060200201356040518082815260200191505060405180910390a26001016115ad565b50505050505050565b6116ac60405180606001604052806023815260200161300760239139612582565b6015546001600160a01b038381169116146116e2576001600160a01b03821660009081526009602052604090206116e2906126a6565b6001600160a01b0382166000818152602d6020908152604091829020805460ff1916851515908117909155825190815291517f03561d5280ebb02280893b1d60978e4a27e7654a149c5d0e7c2cf65389ce16949281900390910190a25050565b600d818154811061174f57fe5b6000918252602090912001546001600160a01b0316905081565b6004546000906001600160a01b0390811690839081168214156117bd5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6117c56127a8565b6117ce8461286e565b600480546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611093565b602b6020526000908152604090205481565b600a546000906001600160a01b03908116908390811682141561189a5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6118a26127a8565b6118ab8461286e565b600a80546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e929181900390910190a16000611093565b61193260405180606001604052806029815260200161302a60299139612582565b8281811580159061194257508082145b611983576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b828110156116825784848281811061199a57fe5b90506020020135601f60008989858181106119b157fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106119f157fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611a3757fe5b905060200201356040518082815260200191505060405180910390a2600101611986565b601a548180821415611aa2576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b611aaa6127a8565b601b546001600160a01b031615611ac357611ac36128c1565b601a805490849055604080518281526020810186905281517fe81d4ac15e5afa1e708e66664eddc697177423d950d133bda8262d8885e6da3b929181900390910190a150505050565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b611b936127a8565b611b9c8161286e565b6033546040516001600160a01b038084169216907ffe7fd0d872def0f65050e9f38fc6691d0c192c694a56f09b04bec5fb2ea61f2b90600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6015546001600160a01b031681565b6000611c116127a8565b611c1a8261286e565b603180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fcb20dab7409e4fb972d9adccb39530520b226ce6940d85c9523a499b950b6ea3929181900390910190a160009392505050565b60075481565b6025546001600160a01b031681565b6026546000906001600160a01b039081169083908116821415611ceb5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611cf36127a8565b611cfc8461286e565b602680546001600160a01b038681166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0f7eb572d1b3053a0a3a33c04151364cf88d163182a5e4e1088cb8e52321e08a9281900390910190a16000611093565b6015546000906001600160a01b039081169083908116821415611db55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611dbd6127a8565b611dc68461286e565b601580546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fe1ddcb2dab8e5b03cfc8c67a0d5861d91d16f7bd2612fd381faf4541d212c9b2929181900390910190a16000611093565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b6025546001600160a01b039081169082908116821415611ec55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611ecd6127a8565b611ed68361286e565b602580546001600160a01b038581166001600160a01b0319831681179093556040805191909216808252602082019390935281517fa5ea5616d5f6dbbaa62fdfcf3856723216eed485c394d9e51ec8e6d40e1d1ac1929181900390910190a150505050565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b602054600090611fab906001600160a01b0316612a88565b670de0b6b3a76400008210611ff9576040805162461bcd60e51b815260206004820152600f60248201526e70657263656e74203e3d203130302560881b604482015290519081900360640190fd5b6120028461286e565b61200b8361286e565b6020805460218054602280546001600160a01b038a81166001600160a01b0319808816821789558b8316908616179095559188905560408051958316808752968601949094528351929091169390927f29f06ea15931797ebaed313d81d100963dc22cb213cb4ce2737b5a62b1a8b1e892918290030190a1604080516001600160a01b0380851682528816602082015281517f8de763046d7b8f08b6c3d03543de1d615309417842bb5d2d62f110f65809ddac929181900390910190a1604080518281526020810187905281517f0893f8f4101baaabbeb513f96761e7a36eb837403c82cc651c292a4abdc94ed7929181900390910190a1600093505050505b9392505050565b6026546001600160a01b031681565b6008602052816000526040600020818154811061213a57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526009602052604081206001015482808214156121ef576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61221060405180606001604052806025815260200161309560259139612582565b6122198561286e565b6001600160a01b038516600090815260096020526040902061223a816126a6565b612242612f24565b506040805160208101909152858152612259612f24565b506040805160208101909152670c7d713b49da0000815261227a81836127fa565b156122955761228b60066008612808565b9550505050612385565b861580159061231e5750600480546040805163fc57d4df60e01b81526001600160a01b038c8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d602081101561231a57600080fd5b5051155b1561232f5761228b600d6009612808565b6001830180549088905560408051828152602081018a905281516001600160a01b038c16927f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5928290030190a260009650505050505b505092915050565b6001600160a01b0382166000908152602960205260408120818360088111156123b257fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b603260209081526000928352604080842090915290825290205460ff1681565b6028546000906001600160a01b0390811690839081168214156124495760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6124516127a8565b61245a8461286e565b602880546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0f1eca7612e020f6e4582bcead0573eba4b5f7b56668754c6aed82ef12057dd4929181900390910190a16000611093565b6000546001600160a01b031681565b601a5481565b60006124df612aea565b60185460ff161580156124fa5750601854610100900460ff16155b61253b576040805162461bcd60e51b815260206004820152600d60248201526c159052481a5cc81c185d5cd959609a1b604482015290519081900360640190fd5b6015546001600160a01b0316331461256057612559600e6016612808565b90506123c9565b6001600160a01b03831660009081526016602052604081208390559392505050565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156125eb5781810151838201526020016125d3565b50505050905090810190601f1680156126185780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561263657600080fd5b505afa15801561264a573d6000803e3d6000fd5b505050506040513d602081101561266057600080fd5b50516126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b805460ff166126a3576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612711906126a6565b6001600160a01b0383166000908152602960205260408120829184600881111561273757fe5b81526020810191909152604001600020805460ff191691151591909117905581600881111561276257fe5b60408051831515815290516001600160a01b038616917f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d919081900360200190a3505050565b6000546001600160a01b031633146127f8576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b565b5190511090565b5190511190565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601381111561283757fe5b83601781111561284357fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561210b57fe5b6001600160a01b0381166126a3576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b601c5415806128d85750601c546128d6612b3d565b105b156128e2576127f8565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561293257600080fd5b505afa158015612946573d6000803e3d6000fd5b505050506040513d602081101561295c57600080fd5b505190508061296c5750506127f8565b60008061298261297a612b3d565b601c54612b41565b90506000612992601a5483612b7b565b90508084106129a3578092506129a7565b8392505b601d548310156129bb5750505050506127f8565b6129c3612b3d565b601c55601b546129e6906001600160a01b0387811691168563ffffffff612bbd16565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a6957600080fd5b505af1158015612a7d573d6000803e3d6000fd5b505050505050505050565b6000546001600160a01b0316331480612aa95750336001600160a01b038216145b6126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b60185462010000900460ff16156127f8576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b4390565b600061210b8383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250612c14565b600061210b83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250612cab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612c0f908490612d2a565b505050565b60008184841115612ca35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c68578181015183820152602001612c50565b50505050905090810190601f168015612c955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000831580612cb8575082155b15612cc55750600061210b565b83830283858281612cd257fe5b04148390612d215760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c68578181015183820152602001612c50565b50949350505050565b612d3c826001600160a01b0316612ee8565b612d8d576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612dcb5780518252601f199092019160209182019101612dac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612e2d576040519150601f19603f3d011682016040523d82523d6000602084013e612e32565b606091505b509150915081612e89576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115612ee257808060200190516020811015612ea557600080fd5b5051612ee25760405162461bcd60e51b815260040180806020018281038252602a815260200180612f6a602a913960400191505060405180910390fd5b50505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612f1c57508115155b949350505050565b604051806020016040528060008152509056fe5f736574466f726365644c69717569646174696f6e466f725573657228616464726573732c616464726573732c626f6f6c295361666542455032303a204245503230206f7065726174696f6e20646964206e6f7420737563636565645f736574416374696f6e7350617573656428616464726573735b5d2c75696e74385b5d2c626f6f6c295f7365744c69717569646174696f6e496e63656e746976652875696e74323536295f7365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d295f736574466f726365644c69717569646174696f6e28616464726573732c626f6f6c295f7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d296f6c642076616c75652069732073616d65206173206e65772076616c756500006f6c6420616464726573732069732073616d65206173206e657720616464726573735f736574436f6c6c61746572616c466163746f7228616464726573732c75696e7432353629a265627a7a72315820034f3ebdeb182cf618d5e109722b114fef9a311a07dd953a936b74841c4e9bf964736f6c63430005100032", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103f15760003560e01c80637dc0d1d011610215578063bf32442d11610125578063e37d4b79116100b8578063f445d70311610087578063f445d70314610cdf578063f519fc3014610d0d578063f851a44014610d33578063fa6331d814610d3b578063fd51a3ad14610d43576103f1565b8063e37d4b7914610c56578063e4028eee14610c7c578063e85a296014610ca8578063e875544614610cd7576103f1565b8063d24febad116100f4578063d24febad14610be4578063d3270f9914610c1a578063dce1544914610c22578063dcfbc0c714610c4e576103f1565b8063bf32442d14610ba8578063c5b4db5514610bb0578063c5f956af14610bd4578063c7ee005e14610bdc576103f1565b80639bb27d62116101a8578063b8324c7c11610177578063b8324c7c14610afe578063bb82aa5e14610b4c578063bb85745014610b54578063bbb8864a14610b7a578063bec04f7214610ba0576103f1565b80639bb27d6214610aa25780639bf34cbb14610aaa5780639cfdd9e614610ad0578063b2eafc3914610af6576103f1565b8063919a3736116101e4578063919a373614610a465780639254f5e514610a6c5780639460c8b514610a7457806394b2294b14610a9a576103f1565b80637dc0d1d0146109aa5780638a7dc165146109b25780638c1ac18a146109d85780638e8f294b146109fe576103f1565b8063425fad581161031057806352d84d1e116102a3578063607ef6c111610272578063607ef6c1146108b75780636662c7c914610975578063719f701b14610992578063765513831461099a5780637d172bd5146109a2576103f1565b806352d84d1e1461082857806355ee1fe1146108455780635dd3fc9d1461086b5780635f5af1aa14610891576103f1565b80634ef233fc116102df5780634ef233fc146106f95780634fd42e171461071f57806351a485e41461073c578063522c656b146107fa576103f1565b8063425fad58146106915780634a584432146106995780634ada90af146106bf5780634e0853db146106c7576103f1565b806326782247116103885780632ec04124116103575780632ec0412414610621578063317b0b771461063e5780634088c73e1461065b57806341a18d2c14610663576103f1565b806326782247146105145780632a6a60651461051c5780632b5d790c1461053b5780632bc7e29e146105fb576103f1565b806310b98338116103c457806310b983381461046c57806317db2163146104ae57806321af4569146104e857806324a3d6221461050c576103f1565b806302c3bcbb146103f657806304ef9d581461042e57806308e0225c146104365780630db4b4e514610464575b600080fd5b61041c6004803603602081101561040c57600080fd5b50356001600160a01b0316610d6f565b60408051918252519081900360200190f35b61041c610d81565b61041c6004803603604081101561044c57600080fd5b506001600160a01b0381358116916020013516610d87565b61041c610da4565b61049a6004803603604081101561048257600080fd5b506001600160a01b0381358116916020013516610daa565b604080519115158252519081900360200190f35b6104e6600480360360608110156104c457600080fd5b506001600160a01b038135811691602081013590911690604001351515610dca565b005b6104f0610e8f565b604080516001600160a01b039092168252519081900360200190f35b6104f0610e9e565b6104f0610ead565b61049a6004803603602081101561053257600080fd5b50351515610ebc565b6104e66004803603606081101561055157600080fd5b810190602081018135600160201b81111561056b57600080fd5b82018360208201111561057d57600080fd5b803590602001918460208302840111600160201b8311171561059e57600080fd5b919390929091602081019035600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460208302840111600160201b831117156105ee57600080fd5b9193509150351515610f4e565b61041c6004803603602081101561061157600080fd5b50356001600160a01b0316610fea565b61041c6004803603602081101561063757600080fd5b5035610ffc565b61041c6004803603602081101561065457600080fd5b503561109e565b61049a6111c8565b61041c6004803603604081101561067957600080fd5b506001600160a01b03813581169160200135166111d1565b61049a6111ee565b61041c600480360360208110156106af57600080fd5b50356001600160a01b03166111fd565b61041c61120f565b6104e6600480360360608110156106dd57600080fd5b506001600160a01b038135169060208101359060400135611215565b6104e66004803603602081101561070f57600080fd5b50356001600160a01b03166112fa565b61041c6004803603602081101561073557600080fd5b5035611434565b6104e66004803603604081101561075257600080fd5b810190602081018135600160201b81111561076c57600080fd5b82018360208201111561077e57600080fd5b803590602001918460208302840111600160201b8311171561079f57600080fd5b919390929091602081019035600160201b8111156107bc57600080fd5b8201836020820111156107ce57600080fd5b803590602001918460208302840111600160201b831117156107ef57600080fd5b509092509050611538565b6104e66004803603604081101561081057600080fd5b506001600160a01b038135169060200135151561168b565b6104f06004803603602081101561083e57600080fd5b5035611742565b61041c6004803603602081101561085b57600080fd5b50356001600160a01b0316611769565b61041c6004803603602081101561088157600080fd5b50356001600160a01b0316611834565b61041c600480360360208110156108a757600080fd5b50356001600160a01b0316611846565b6104e6600480360360408110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460208302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460208302840111600160201b8311171561096a57600080fd5b509092509050611911565b6104e66004803603602081101561098b57600080fd5b5035611a5b565b61041c611b0c565b61049a611b12565b6104f0611b20565b6104f0611b2f565b61041c600480360360208110156109c857600080fd5b50356001600160a01b0316611b3e565b61049a600480360360208110156109ee57600080fd5b50356001600160a01b0316611b50565b610a2460048036036020811015610a1457600080fd5b50356001600160a01b0316611b65565b6040805193151584526020840192909252151582820152519081900360600190f35b6104e660048036036020811015610a5c57600080fd5b50356001600160a01b0316611b8b565b6104f0611bf8565b61041c60048036036020811015610a8a57600080fd5b50356001600160a01b0316611c07565b61041c611c82565b6104f0611c88565b61041c60048036036020811015610ac057600080fd5b50356001600160a01b0316611c97565b61041c60048036036020811015610ae657600080fd5b50356001600160a01b0316611d61565b6104f0611e2c565b610b2460048036036020811015610b1457600080fd5b50356001600160a01b0316611e3b565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104f0611e65565b6104e660048036036020811015610b6a57600080fd5b50356001600160a01b0316611e74565b61041c60048036036020811015610b9057600080fd5b50356001600160a01b0316611f3b565b61041c611f4d565b6104f0611f53565b610bb8611f62565b604080516001600160e01b039092168252519081900360200190f35b6104f0611f75565b6104f0611f84565b61041c60048036036060811015610bfa57600080fd5b506001600160a01b03813581169160208101359091169060400135611f93565b6104f0612112565b6104f060048036036040811015610c3857600080fd5b506001600160a01b038135169060200135612121565b6104f0612156565b610b2460048036036020811015610c6c57600080fd5b50356001600160a01b0316612165565b61041c60048036036040811015610c9257600080fd5b506001600160a01b03813516906020013561218f565b61049a60048036036040811015610cbe57600080fd5b5080356001600160a01b0316906020013560ff1661238d565b61041c6123cf565b61049a60048036036040811015610cf557600080fd5b506001600160a01b03813581169160200135166123d5565b61041c60048036036020811015610d2357600080fd5b50356001600160a01b03166123f5565b6104f06124c0565b61041c6124cf565b61041c60048036036040811015610d5957600080fd5b506001600160a01b0381351690602001356124d5565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b610deb604051806060016040528060328152602001612f3860329139612582565b6015546001600160a01b03838116911614610e21576001600160a01b0382166000908152600960205260409020610e21906126a6565b6001600160a01b03838116600081815260326020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fc080966e9e93529edc1b244180c245bc60f3d86f1e690a17651a5e428746a8cd9281900390910190a3505050565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b6000610efc6040518060400160405280601881526020017f5f73657450726f746f636f6c50617573656428626f6f6c290000000000000000815250612582565b6018805483151562010000810262ff0000199092169190911790915560408051918252517fd7500633dd3ddd74daa7af62f8c8404c7fe4a81da179998db851696bed004b389181900360200190a15090565b610f6f604051806060016040528060298152602001612f9460299139612582565b838260005b82811015610fe05760005b82811015610fd757610fcf898984818110610f9657fe5b905060200201356001600160a01b0316888884818110610fb257fe5b90506020020135600881118015610fc857600080fd5b50876126f0565b600101610f7f565b50600101610f74565b5050505050505050565b60166020526000908152604090205481565b60006017548280821415611045576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61104d6127a8565b6017805490859055604080518281526020810187905281517f73747d68b346dce1e932bcd238282e7ac84c01569e1f8d0469c222fdc6e9d5a4929181900390910190a160005b9350505b5050919050565b600060055482808214156110e7576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b6110ef6127a8565b6110f7612f24565b50604080516020810190915284815261110e612f24565b506040805160208101909152670c7d713b49da0000815261112d612f24565b50604080516020810190915266b1a2bc2ec50000815261114d82846127fa565b8061115d575061115d8184612801565b156111775761116d600580612808565b9550505050611097565b600580549088905560408051828152602081018a905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a1600098975050505050505050565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b601b546001600160a01b0390811690849081168214156112665760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b61126e6127a8565b6112778561286e565b601b546001600160a01b031615611290576112906128c1565b601b80546001600160a01b0319166001600160a01b038716908117909155601c859055601d849055604080518681526020810186905281517f7059037d74ee16b0fb06a4a30f3348dd2635f301f92e373c92899a25a522ef6e929181900390910190a25050505050565b6113026127a8565b61130b8161286e565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b50516033549091506001600160a01b038083169116146113d7576040805162461bcd60e51b815260206004820152601a60248201527f696e76616c6964207876732076746f6b656e2061646472657373000000000000604482015290519081900360640190fd5b6034546040516001600160a01b038085169216907f2565e1579c0926afb7113edbfd85373e85cadaa3e0346f04de19686a2bb86ed190600090a350603480546001600160a01b0319166001600160a01b0392909216919091179055565b6000600654828082141561147d576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61149e604051806060016040528060218152602001612fbd60219139612582565b670de0b6b3a76400008410156114ee576040805162461bcd60e51b815260206004820152601060248201526f0d2dcc6cadce8d2ecca40784062ca62760831b604482015290519081900360640190fd5b6006805490859055604080518281526020810187905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611093565b611559604051806060016040528060298152602001612fde60299139612582565b8281811580159061156957508082145b6115aa576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b82811015611682578484828181106115c157fe5b90506020020135602760008989858181106115d857fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000208190555086868281811061161857fe5b905060200201356001600160a01b03166001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f886868481811061165e57fe5b905060200201356040518082815260200191505060405180910390a26001016115ad565b50505050505050565b6116ac60405180606001604052806023815260200161300760239139612582565b6015546001600160a01b038381169116146116e2576001600160a01b03821660009081526009602052604090206116e2906126a6565b6001600160a01b0382166000818152602d6020908152604091829020805460ff1916851515908117909155825190815291517f03561d5280ebb02280893b1d60978e4a27e7654a149c5d0e7c2cf65389ce16949281900390910190a25050565b600d818154811061174f57fe5b6000918252602090912001546001600160a01b0316905081565b6004546000906001600160a01b0390811690839081168214156117bd5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6117c56127a8565b6117ce8461286e565b600480546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611093565b602b6020526000908152604090205481565b600a546000906001600160a01b03908116908390811682141561189a5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6118a26127a8565b6118ab8461286e565b600a80546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e929181900390910190a16000611093565b61193260405180606001604052806029815260200161302a60299139612582565b8281811580159061194257508082145b611983576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b828110156116825784848281811061199a57fe5b90506020020135601f60008989858181106119b157fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106119f157fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611a3757fe5b905060200201356040518082815260200191505060405180910390a2600101611986565b601a548180821415611aa2576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b611aaa6127a8565b601b546001600160a01b031615611ac357611ac36128c1565b601a805490849055604080518281526020810186905281517fe81d4ac15e5afa1e708e66664eddc697177423d950d133bda8262d8885e6da3b929181900390910190a150505050565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b611b936127a8565b611b9c8161286e565b6033546040516001600160a01b038084169216907ffe7fd0d872def0f65050e9f38fc6691d0c192c694a56f09b04bec5fb2ea61f2b90600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6015546001600160a01b031681565b6000611c116127a8565b611c1a8261286e565b603180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fcb20dab7409e4fb972d9adccb39530520b226ce6940d85c9523a499b950b6ea3929181900390910190a160009392505050565b60075481565b6025546001600160a01b031681565b6026546000906001600160a01b039081169083908116821415611ceb5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611cf36127a8565b611cfc8461286e565b602680546001600160a01b038681166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0f7eb572d1b3053a0a3a33c04151364cf88d163182a5e4e1088cb8e52321e08a9281900390910190a16000611093565b6015546000906001600160a01b039081169083908116821415611db55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611dbd6127a8565b611dc68461286e565b601580546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fe1ddcb2dab8e5b03cfc8c67a0d5861d91d16f7bd2612fd381faf4541d212c9b2929181900390910190a16000611093565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b6025546001600160a01b039081169082908116821415611ec55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611ecd6127a8565b611ed68361286e565b602580546001600160a01b038581166001600160a01b0319831681179093556040805191909216808252602082019390935281517fa5ea5616d5f6dbbaa62fdfcf3856723216eed485c394d9e51ec8e6d40e1d1ac1929181900390910190a150505050565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b602054600090611fab906001600160a01b0316612a88565b670de0b6b3a76400008210611ff9576040805162461bcd60e51b815260206004820152600f60248201526e70657263656e74203e3d203130302560881b604482015290519081900360640190fd5b6120028461286e565b61200b8361286e565b6020805460218054602280546001600160a01b038a81166001600160a01b0319808816821789558b8316908616179095559188905560408051958316808752968601949094528351929091169390927f29f06ea15931797ebaed313d81d100963dc22cb213cb4ce2737b5a62b1a8b1e892918290030190a1604080516001600160a01b0380851682528816602082015281517f8de763046d7b8f08b6c3d03543de1d615309417842bb5d2d62f110f65809ddac929181900390910190a1604080518281526020810187905281517f0893f8f4101baaabbeb513f96761e7a36eb837403c82cc651c292a4abdc94ed7929181900390910190a1600093505050505b9392505050565b6026546001600160a01b031681565b6008602052816000526040600020818154811061213a57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526009602052604081206001015482808214156121ef576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61221060405180606001604052806025815260200161309560259139612582565b6122198561286e565b6001600160a01b038516600090815260096020526040902061223a816126a6565b612242612f24565b506040805160208101909152858152612259612f24565b506040805160208101909152670c7d713b49da0000815261227a81836127fa565b156122955761228b60066008612808565b9550505050612385565b861580159061231e5750600480546040805163fc57d4df60e01b81526001600160a01b038c8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d602081101561231a57600080fd5b5051155b1561232f5761228b600d6009612808565b6001830180549088905560408051828152602081018a905281516001600160a01b038c16927f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5928290030190a260009650505050505b505092915050565b6001600160a01b0382166000908152602960205260408120818360088111156123b257fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b603260209081526000928352604080842090915290825290205460ff1681565b6028546000906001600160a01b0390811690839081168214156124495760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6124516127a8565b61245a8461286e565b602880546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0f1eca7612e020f6e4582bcead0573eba4b5f7b56668754c6aed82ef12057dd4929181900390910190a16000611093565b6000546001600160a01b031681565b601a5481565b60006124df612aea565b60185460ff161580156124fa5750601854610100900460ff16155b61253b576040805162461bcd60e51b815260206004820152600d60248201526c159052481a5cc81c185d5cd959609a1b604482015290519081900360640190fd5b6015546001600160a01b0316331461256057612559600e6016612808565b90506123c9565b6001600160a01b03831660009081526016602052604081208390559392505050565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156125eb5781810151838201526020016125d3565b50505050905090810190601f1680156126185780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561263657600080fd5b505afa15801561264a573d6000803e3d6000fd5b505050506040513d602081101561266057600080fd5b50516126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b805460ff166126a3576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612711906126a6565b6001600160a01b0383166000908152602960205260408120829184600881111561273757fe5b81526020810191909152604001600020805460ff191691151591909117905581600881111561276257fe5b60408051831515815290516001600160a01b038616917f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d919081900360200190a3505050565b6000546001600160a01b031633146127f8576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b565b5190511090565b5190511190565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601381111561283757fe5b83601781111561284357fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561210b57fe5b6001600160a01b0381166126a3576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b601c5415806128d85750601c546128d6612b3d565b105b156128e2576127f8565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561293257600080fd5b505afa158015612946573d6000803e3d6000fd5b505050506040513d602081101561295c57600080fd5b505190508061296c5750506127f8565b60008061298261297a612b3d565b601c54612b41565b90506000612992601a5483612b7b565b90508084106129a3578092506129a7565b8392505b601d548310156129bb5750505050506127f8565b6129c3612b3d565b601c55601b546129e6906001600160a01b0387811691168563ffffffff612bbd16565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a6957600080fd5b505af1158015612a7d573d6000803e3d6000fd5b505050505050505050565b6000546001600160a01b0316331480612aa95750336001600160a01b038216145b6126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b60185462010000900460ff16156127f8576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b4390565b600061210b8383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250612c14565b600061210b83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250612cab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612c0f908490612d2a565b505050565b60008184841115612ca35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c68578181015183820152602001612c50565b50505050905090810190601f168015612c955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000831580612cb8575082155b15612cc55750600061210b565b83830283858281612cd257fe5b04148390612d215760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c68578181015183820152602001612c50565b50949350505050565b612d3c826001600160a01b0316612ee8565b612d8d576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612dcb5780518252601f199092019160209182019101612dac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612e2d576040519150601f19603f3d011682016040523d82523d6000602084013e612e32565b606091505b509150915081612e89576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115612ee257808060200190516020811015612ea557600080fd5b5051612ee25760405162461bcd60e51b815260040180806020018281038252602a815260200180612f6a602a913960400191505060405180910390fd5b50505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612f1c57508115155b949350505050565b604051806020016040528060008152509056fe5f736574466f726365644c69717569646174696f6e466f725573657228616464726573732c616464726573732c626f6f6c295361666542455032303a204245503230206f7065726174696f6e20646964206e6f7420737563636565645f736574416374696f6e7350617573656428616464726573735b5d2c75696e74385b5d2c626f6f6c295f7365744c69717569646174696f6e496e63656e746976652875696e74323536295f7365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d295f736574466f726365644c69717569646174696f6e28616464726573732c626f6f6c295f7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d296f6c642076616c75652069732073616d65206173206e65772076616c756500006f6c6420616464726573732069732073616d65206173206e657720616464726573735f736574436f6c6c61746572616c466163746f7228616464726573732c75696e7432353629a265627a7a72315820034f3ebdeb182cf618d5e109722b114fef9a311a07dd953a936b74841c4e9bf964736f6c63430005100032", + "numDeployments": 3, + "solcInputHash": "ce1a4122e5f4f14eccfd5d8b352422cb", + "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"pauseState\",\"type\":\"bool\"}],\"name\":\"ActionPausedMarket\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"ActionProtocolPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"IsForcedLiquidationEnabledForUserUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"IsForcedLiquidationEnabledUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlAddress\",\"type\":\"address\"}],\"name\":\"NewAccessControl\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBorrowCap\",\"type\":\"uint256\"}],\"name\":\"NewBorrowCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCloseFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCloseFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCollateralFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCollateralFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldComptrollerLens\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newComptrollerLens\",\"type\":\"address\"}],\"name\":\"NewComptrollerLens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":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\":\"address\",\"name\":\"oldLiquidatorContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLiquidatorContract\",\"type\":\"address\"}],\"name\":\"NewLiquidatorContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldPauseGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPauseGuardian\",\"type\":\"address\"}],\"name\":\"NewPauseGuardian\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract PriceOracle\",\"name\":\"oldPriceOracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract PriceOracle\",\"name\":\"newPriceOracle\",\"type\":\"address\"}],\"name\":\"NewPriceOracle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IPrime\",\"name\":\"oldPrimeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IPrime\",\"name\":\"newPrimeToken\",\"type\":\"address\"}],\"name\":\"NewPrimeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSupplyCap\",\"type\":\"uint256\"}],\"name\":\"NewSupplyCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldTreasuryAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTreasuryAddress\",\"type\":\"address\"}],\"name\":\"NewTreasuryAddress\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldTreasuryGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTreasuryGuardian\",\"type\":\"address\"}],\"name\":\"NewTreasuryGuardian\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldTreasuryPercent\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newTreasuryPercent\",\"type\":\"uint256\"}],\"name\":\"NewTreasuryPercent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VAIControllerInterface\",\"name\":\"oldVAIController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract VAIControllerInterface\",\"name\":\"newVAIController\",\"type\":\"address\"}],\"name\":\"NewVAIController\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVAIMintRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVAIMintRate\",\"type\":\"uint256\"}],\"name\":\"NewVAIMintRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"releaseStartBlock_\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"releaseInterval_\",\"type\":\"uint256\"}],\"name\":\"NewVAIVaultInfo\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVenusVAIVaultRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVenusVAIVaultRate\",\"type\":\"uint256\"}],\"name\":\"NewVenusVAIVaultRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldXVS\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newXVS\",\"type\":\"address\"}],\"name\":\"NewXVSToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldXVSVToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newXVSVToken\",\"type\":\"address\"}],\"name\":\"NewXVSVToken\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAccessControlAddress\",\"type\":\"address\"}],\"name\":\"_setAccessControl\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"markets_\",\"type\":\"address[]\"},{\"internalType\":\"enum ComptrollerTypes.Action[]\",\"name\":\"actions_\",\"type\":\"uint8[]\"},{\"internalType\":\"bool\",\"name\":\"paused_\",\"type\":\"bool\"}],\"name\":\"_setActionsPaused\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"_setCloseFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"_setCollateralFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"comptrollerLens_\",\"type\":\"address\"}],\"name\":\"_setComptrollerLens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"_setForcedLiquidation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"_setForcedLiquidationForUser\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"_setLiquidationIncentive\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newLiquidatorContract_\",\"type\":\"address\"}],\"name\":\"_setLiquidatorContract\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newBorrowCaps\",\"type\":\"uint256[]\"}],\"name\":\"_setMarketBorrowCaps\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newSupplyCaps\",\"type\":\"uint256[]\"}],\"name\":\"_setMarketSupplyCaps\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPauseGuardian\",\"type\":\"address\"}],\"name\":\"_setPauseGuardian\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"_setPriceOracle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"_prime\",\"type\":\"address\"}],\"name\":\"_setPrimeToken\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"_setProtocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newTreasuryGuardian\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newTreasuryAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newTreasuryPercent\",\"type\":\"uint256\"}],\"name\":\"_setTreasuryData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"vaiController_\",\"type\":\"address\"}],\"name\":\"_setVAIController\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newVAIMintRate\",\"type\":\"uint256\"}],\"name\":\"_setVAIMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"releaseStartBlock_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minReleaseAmount_\",\"type\":\"uint256\"}],\"name\":\"_setVAIVaultInfo\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"venusVAIVaultRate_\",\"type\":\"uint256\"}],\"name\":\"_setVenusVAIVaultRate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"xvs_\",\"type\":\"address\"}],\"name\":\"_setXVSToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"xvsVToken_\",\"type\":\"address\"}],\"name\":\"_setXVSVToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setMintedVAIOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the setters for the states\",\"methods\":{\"_setAccessControl(address)\":{\"details\":\"Allows the contract admin to set the address of access control of this contract\",\"params\":{\"newAccessControlAddress\":\"New address for the access control\"},\"return\":\"uint256 0=success, otherwise will revert\"},\"_setActionsPaused(address[],uint8[],bool)\":{\"details\":\"Allows a privileged role to pause/unpause the protocol action state\",\"params\":{\"actions_\":\"List of action ids to pause/unpause\",\"markets_\":\"Markets to pause/unpause the actions on\",\"paused_\":\"The new paused state (true=paused, false=unpaused)\"}},\"_setCloseFactor(uint256)\":{\"details\":\"Allows the contract admin to set the closeFactor used to liquidate borrows\",\"params\":{\"newCloseFactorMantissa\":\"New close factor, scaled by 1e18\"},\"return\":\"uint256 0=success, otherwise will revert\"},\"_setCollateralFactor(address,uint256)\":{\"details\":\"Allows a privileged role to set the collateralFactorMantissa\",\"params\":{\"newCollateralFactorMantissa\":\"The new collateral factor, scaled by 1e18\",\"vToken\":\"The market to set the factor on\"},\"return\":\"uint256 0=success, otherwise a failure. (See ErrorReporter for details)\"},\"_setComptrollerLens(address)\":{\"details\":\"Set ComptrollerLens contract address\",\"params\":{\"comptrollerLens_\":\"The new ComptrollerLens contract address to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setForcedLiquidation(address,bool)\":{\"details\":\"Allows a privileged role to set enable/disable forced liquidations\",\"params\":{\"enable\":\"Whether to enable forced liquidations\",\"vTokenBorrowed\":\"Borrowed vToken\"}},\"_setForcedLiquidationForUser(address,address,bool)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"enable\":\"Whether to enable forced liquidations\",\"vTokenBorrowed\":\"Borrowed vToken\"}},\"_setLiquidationIncentive(uint256)\":{\"details\":\"Allows a privileged role to set the liquidationIncentiveMantissa\",\"params\":{\"newLiquidationIncentiveMantissa\":\"New liquidationIncentive scaled by 1e18\"},\"return\":\"uint256 0=success, otherwise a failure. (See ErrorReporter for details)\"},\"_setLiquidatorContract(address)\":{\"details\":\"Allows the contract admin to update the address of liquidator contract\",\"params\":{\"newLiquidatorContract_\":\"The new address of the liquidator contract\"}},\"_setMarketBorrowCaps(address[],uint256[])\":{\"details\":\"Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed\",\"params\":{\"newBorrowCaps\":\"The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed\",\"vTokens\":\"The addresses of the markets (tokens) to change the borrow caps for\"}},\"_setMarketSupplyCaps(address[],uint256[])\":{\"details\":\"Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\",\"params\":{\"newSupplyCaps\":\"The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\",\"vTokens\":\"The addresses of the markets (tokens) to change the supply caps for\"}},\"_setPauseGuardian(address)\":{\"details\":\"Allows the contract admin to change the Pause Guardian\",\"params\":{\"newPauseGuardian\":\"The address of the new Pause Guardian\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"_setPriceOracle(address)\":{\"details\":\"Allows the contract admin to set a new price oracle used by the Comptroller\",\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setPrimeToken(address)\":{\"return\":\"uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setProtocolPaused(bool)\":{\"details\":\"Allows a privileged role to pause/unpause protocol\",\"params\":{\"state\":\"The new state (true=paused, false=unpaused)\"},\"return\":\"bool The updated state of the protocol\"},\"_setTreasuryData(address,address,uint256)\":{\"params\":{\"newTreasuryAddress\":\"The new address of the treasury to be set\",\"newTreasuryGuardian\":\"The new address of the treasury guardian to be set\",\"newTreasuryPercent\":\"The new treasury percent to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIController(address)\":{\"details\":\"Admin function to set a new VAI controller\",\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIMintRate(uint256)\":{\"params\":{\"newVAIMintRate\":\"The new VAI mint rate to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIVaultInfo(address,uint256,uint256)\":{\"params\":{\"minReleaseAmount_\":\"The minimum release amount to VAI Vault\",\"releaseStartBlock_\":\"The start block of release to VAI Vault\",\"vault_\":\"The address of the VAI Vault\"}},\"_setVenusVAIVaultRate(uint256)\":{\"params\":{\"venusVAIVaultRate_\":\"The amount of XVS wei per block to distribute to VAI Vault\"}},\"_setXVSToken(address)\":{\"params\":{\"xvs_\":\"The address of the XVS token\"}},\"_setXVSVToken(address)\":{\"params\":{\"xvsVToken_\":\"The address of the XVS vToken\"}},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"setMintedVAIOf(address,uint256)\":{\"params\":{\"amount\":\"The amount of VAI to set to the account\",\"owner\":\"The address of the account to set\"},\"return\":\"The number of minted VAI by `owner`\"}},\"title\":\"SetterFacet\"},\"userdoc\":{\"methods\":{\"_setAccessControl(address)\":{\"notice\":\"Sets the address of the access control of this contract\"},\"_setActionsPaused(address[],uint8[],bool)\":{\"notice\":\"Pause/unpause certain actions\"},\"_setCloseFactor(uint256)\":{\"notice\":\"Sets the closeFactor used when liquidating borrows\"},\"_setCollateralFactor(address,uint256)\":{\"notice\":\"Sets the collateralFactor for a market\"},\"_setForcedLiquidation(address,bool)\":{\"notice\":\"Enables forced liquidations for a market. If forced liquidation is enabled, borrows in the market may be liquidated regardless of the account liquidity\"},\"_setForcedLiquidationForUser(address,address,bool)\":{\"notice\":\"Enables forced liquidations for user's borrows in a certain market. If forced liquidation is enabled, user's borrows in the market may be liquidated regardless of the account liquidity. Forced liquidation may be enabled for a user even if it is not enabled for the entire market.\"},\"_setLiquidationIncentive(uint256)\":{\"notice\":\"Sets liquidationIncentive\"},\"_setLiquidatorContract(address)\":{\"notice\":\"Update the address of the liquidator contract\"},\"_setMarketBorrowCaps(address[],uint256[])\":{\"notice\":\"Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\"},\"_setMarketSupplyCaps(address[],uint256[])\":{\"notice\":\"Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\"},\"_setPauseGuardian(address)\":{\"notice\":\"Admin function to change the Pause Guardian\"},\"_setPriceOracle(address)\":{\"notice\":\"Sets a new price oracle for the comptroller\"},\"_setPrimeToken(address)\":{\"notice\":\"Sets the prime token contract for the comptroller\"},\"_setProtocolPaused(bool)\":{\"notice\":\"Set whole protocol pause/unpause state\"},\"_setTreasuryData(address,address,uint256)\":{\"notice\":\"Set the treasury data.\"},\"_setVAIController(address)\":{\"notice\":\"Sets a new VAI controller\"},\"_setVAIMintRate(uint256)\":{\"notice\":\"Set the VAI mint rate\"},\"_setVAIVaultInfo(address,uint256,uint256)\":{\"notice\":\"Set the VAI Vault infos\"},\"_setVenusVAIVaultRate(uint256)\":{\"notice\":\"Set the amount of XVS distributed per block to VAI Vault\"},\"_setXVSToken(address)\":{\"notice\":\"Set the address of the XVS token\"},\"_setXVSVToken(address)\":{\"notice\":\"Set the address of the XVS vToken\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"setMintedVAIOf(address,uint256)\":{\"notice\":\"Set the minted VAI amount of the `owner`\"}},\"notice\":\"This facet contract contains all the configurational setter functions\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/SetterFacet.sol\":\"SetterFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x06608bb502e91c33fda8c0dd88cc79a49a078fab521bc27d10fc3a69c1da55f4\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/SetterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { ISetterFacet } from \\\"../interfaces/ISetterFacet.sol\\\";\\nimport { PriceOracle } from \\\"../../../Oracle/PriceOracle.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"../../ComptrollerLensInterface.sol\\\";\\nimport { VAIControllerInterface } from \\\"../../../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\nimport { IPrime } from \\\"../../../Tokens/Prime/IPrime.sol\\\";\\n\\n/**\\n * @title SetterFacet\\n * @author Venus\\n * @dev This facet contains all the setters for the states\\n * @notice This facet contract contains all the configurational setter functions\\n */\\ncontract SetterFacet is ISetterFacet, FacetBase {\\n /// @notice Emitted when close factor is changed by admin\\n event NewCloseFactor(uint256 oldCloseFactorMantissa, uint256 newCloseFactorMantissa);\\n\\n /// @notice Emitted when a collateral factor is changed by admin\\n event NewCollateralFactor(\\n VToken indexed vToken,\\n uint256 oldCollateralFactorMantissa,\\n uint256 newCollateralFactorMantissa\\n );\\n\\n /// @notice Emitted when liquidation incentive is changed by admin\\n event NewLiquidationIncentive(uint256 oldLiquidationIncentiveMantissa, uint256 newLiquidationIncentiveMantissa);\\n\\n /// @notice Emitted when price oracle is changed\\n event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle);\\n\\n /// @notice Emitted when borrow cap for a vToken is changed\\n event NewBorrowCap(VToken indexed vToken, uint256 newBorrowCap);\\n\\n /// @notice Emitted when VAIController is changed\\n event NewVAIController(VAIControllerInterface oldVAIController, VAIControllerInterface newVAIController);\\n\\n /// @notice Emitted when VAI mint rate is changed by admin\\n event NewVAIMintRate(uint256 oldVAIMintRate, uint256 newVAIMintRate);\\n\\n /// @notice Emitted when protocol state is changed by admin\\n event ActionProtocolPaused(bool state);\\n\\n /// @notice Emitted when treasury guardian is changed\\n event NewTreasuryGuardian(address oldTreasuryGuardian, address newTreasuryGuardian);\\n\\n /// @notice Emitted when treasury address is changed\\n event NewTreasuryAddress(address oldTreasuryAddress, address newTreasuryAddress);\\n\\n /// @notice Emitted when treasury percent is changed\\n event NewTreasuryPercent(uint256 oldTreasuryPercent, uint256 newTreasuryPercent);\\n\\n /// @notice Emitted when liquidator adress is changed\\n event NewLiquidatorContract(address oldLiquidatorContract, address newLiquidatorContract);\\n\\n /// @notice Emitted when ComptrollerLens address is changed\\n event NewComptrollerLens(address oldComptrollerLens, address newComptrollerLens);\\n\\n /// @notice Emitted when supply cap for a vToken is changed\\n event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /// @notice Emitted when pause guardian is changed\\n event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken indexed vToken, Action indexed action, bool pauseState);\\n\\n /// @notice Emitted when VAI Vault info is changed\\n event NewVAIVaultInfo(address indexed vault_, uint256 releaseStartBlock_, uint256 releaseInterval_);\\n\\n /// @notice Emitted when Venus VAI Vault rate is changed\\n event NewVenusVAIVaultRate(uint256 oldVenusVAIVaultRate, uint256 newVenusVAIVaultRate);\\n\\n /// @notice Emitted when prime token contract address is changed\\n event NewPrimeToken(IPrime oldPrimeToken, IPrime newPrimeToken);\\n\\n /// @notice Emitted when forced liquidation is enabled or disabled for all users in a market\\n event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);\\n\\n /// @notice Emitted when forced liquidation is enabled or disabled for a user borrowing in a market\\n event IsForcedLiquidationEnabledForUserUpdated(address indexed borrower, address indexed vToken, bool enable);\\n\\n /// @notice Emitted when XVS token address is changed\\n event NewXVSToken(address indexed oldXVS, address indexed newXVS);\\n\\n /// @notice Emitted when XVS vToken address is changed\\n event NewXVSVToken(address indexed oldXVSVToken, address indexed newXVSVToken);\\n\\n /**\\n * @notice Compare two addresses to ensure they are different\\n * @param oldAddress The original address to compare\\n * @param newAddress The new address to compare\\n */\\n modifier compareAddress(address oldAddress, address newAddress) {\\n require(oldAddress != newAddress, \\\"old address is same as new address\\\");\\n _;\\n }\\n\\n /**\\n * @notice Compare two values to ensure they are different\\n * @param oldValue The original value to compare\\n * @param newValue The new value to compare\\n */\\n modifier compareValue(uint256 oldValue, uint256 newValue) {\\n require(oldValue != newValue, \\\"old value is same as new value\\\");\\n _;\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the comptroller\\n * @dev Allows the contract admin to set a new price oracle used by the Comptroller\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setPriceOracle(\\n PriceOracle newOracle\\n ) external compareAddress(address(oracle), address(newOracle)) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(address(newOracle));\\n\\n // Track the old oracle for the comptroller\\n PriceOracle oldOracle = oracle;\\n\\n // Set comptroller's oracle to newOracle\\n oracle = newOracle;\\n\\n // Emit NewPriceOracle(oldOracle, newOracle)\\n emit NewPriceOracle(oldOracle, newOracle);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the closeFactor used when liquidating borrows\\n * @dev Allows the contract admin to set the closeFactor used to liquidate borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @return uint256 0=success, otherwise will revert\\n */\\n function _setCloseFactor(\\n uint256 newCloseFactorMantissa\\n ) external compareValue(closeFactorMantissa, newCloseFactorMantissa) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n\\n Exp memory newCloseFactorExp = Exp({ mantissa: newCloseFactorMantissa });\\n\\n //-- Check close factor <= 0.9\\n Exp memory highLimit = Exp({ mantissa: closeFactorMaxMantissa });\\n //-- Check close factor >= 0.05\\n Exp memory lowLimit = Exp({ mantissa: closeFactorMinMantissa });\\n\\n if (lessThanExp(highLimit, newCloseFactorExp) || greaterThanExp(lowLimit, newCloseFactorExp)) {\\n return fail(Error.INVALID_CLOSE_FACTOR, FailureInfo.SET_CLOSE_FACTOR_VALIDATION);\\n }\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the address of the access control of this contract\\n * @dev Allows the contract admin to set the address of access control of this contract\\n * @param newAccessControlAddress New address for the access control\\n * @return uint256 0=success, otherwise will revert\\n */\\n function _setAccessControl(\\n address newAccessControlAddress\\n ) external compareAddress(accessControl, newAccessControlAddress) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(newAccessControlAddress);\\n\\n address oldAccessControlAddress = accessControl;\\n\\n accessControl = newAccessControlAddress;\\n emit NewAccessControl(oldAccessControlAddress, newAccessControlAddress);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev Allows a privileged role to set the collateralFactorMantissa\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\\n */\\n function _setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa\\n )\\n external\\n compareValue(markets[address(vToken)].collateralFactorMantissa, newCollateralFactorMantissa)\\n returns (uint256)\\n {\\n // Check caller is allowed by access control manager\\n ensureAllowed(\\\"_setCollateralFactor(address,uint256)\\\");\\n ensureNonzeroAddress(address(vToken));\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n ensureListed(market);\\n\\n Exp memory newCollateralFactorExp = Exp({ mantissa: newCollateralFactorMantissa });\\n\\n //-- Check collateral factor <= 0.9\\n Exp memory highLimit = Exp({ mantissa: collateralFactorMaxMantissa });\\n if (lessThanExp(highLimit, newCollateralFactorExp)) {\\n return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION);\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(vToken) == 0) {\\n return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE);\\n }\\n\\n // Set market's collateral factor to new collateral factor, remember old value\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n\\n // Emit event with asset, old collateral factor, and new collateral factor\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev Allows a privileged role to set the liquidationIncentiveMantissa\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\\n */\\n function _setLiquidationIncentive(\\n uint256 newLiquidationIncentiveMantissa\\n ) external compareValue(liquidationIncentiveMantissa, newLiquidationIncentiveMantissa) returns (uint256) {\\n ensureAllowed(\\\"_setLiquidationIncentive(uint256)\\\");\\n\\n require(newLiquidationIncentiveMantissa >= 1e18, \\\"incentive < 1e18\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n // Set liquidation incentive to new incentive\\n liquidationIncentiveMantissa = newLiquidationIncentiveMantissa;\\n\\n // Emit event with old incentive, new incentive\\n emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Update the address of the liquidator contract\\n * @dev Allows the contract admin to update the address of liquidator contract\\n * @param newLiquidatorContract_ The new address of the liquidator contract\\n */\\n function _setLiquidatorContract(\\n address newLiquidatorContract_\\n ) external compareAddress(liquidatorContract, newLiquidatorContract_) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(newLiquidatorContract_);\\n address oldLiquidatorContract = liquidatorContract;\\n liquidatorContract = newLiquidatorContract_;\\n emit NewLiquidatorContract(oldLiquidatorContract, newLiquidatorContract_);\\n }\\n\\n /**\\n * @notice Admin function to change the Pause Guardian\\n * @dev Allows the contract admin to change the Pause Guardian\\n * @param newPauseGuardian The address of the new Pause Guardian\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function _setPauseGuardian(\\n address newPauseGuardian\\n ) external compareAddress(pauseGuardian, newPauseGuardian) returns (uint256) {\\n ensureAdmin();\\n ensureNonzeroAddress(newPauseGuardian);\\n\\n // Save current value for inclusion in log\\n address oldPauseGuardian = pauseGuardian;\\n // Store pauseGuardian with value newPauseGuardian\\n pauseGuardian = newPauseGuardian;\\n\\n // Emit NewPauseGuardian(OldPauseGuardian, NewPauseGuardian)\\n emit NewPauseGuardian(oldPauseGuardian, newPauseGuardian);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\\n * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed\\n * @param vTokens The addresses of the markets (tokens) to change the borrow caps for\\n * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed\\n */\\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n ensureAllowed(\\\"_setMarketBorrowCaps(address[],uint256[])\\\");\\n\\n uint256 numMarkets = vTokens.length;\\n uint256 numBorrowCaps = newBorrowCaps.length;\\n\\n require(numMarkets != 0 && numMarkets == numBorrowCaps, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numMarkets; ++i) {\\n borrowCaps[address(vTokens[i])] = newBorrowCaps[i];\\n emit NewBorrowCap(vTokens[i], newBorrowCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\\n * @dev Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\\n * @param vTokens The addresses of the markets (tokens) to change the supply caps for\\n * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\\n */\\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n ensureAllowed(\\\"_setMarketSupplyCaps(address[],uint256[])\\\");\\n\\n uint256 numMarkets = vTokens.length;\\n uint256 numSupplyCaps = newSupplyCaps.length;\\n\\n require(numMarkets != 0 && numMarkets == numSupplyCaps, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numMarkets; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Set whole protocol pause/unpause state\\n * @dev Allows a privileged role to pause/unpause protocol\\n * @param state The new state (true=paused, false=unpaused)\\n * @return bool The updated state of the protocol\\n */\\n function _setProtocolPaused(bool state) external returns (bool) {\\n ensureAllowed(\\\"_setProtocolPaused(bool)\\\");\\n\\n protocolPaused = state;\\n emit ActionProtocolPaused(state);\\n return state;\\n }\\n\\n /**\\n * @notice Pause/unpause certain actions\\n * @dev Allows a privileged role to pause/unpause the protocol action state\\n * @param markets_ Markets to pause/unpause the actions on\\n * @param actions_ List of action ids to pause/unpause\\n * @param paused_ The new paused state (true=paused, false=unpaused)\\n */\\n function _setActionsPaused(address[] calldata markets_, Action[] calldata actions_, bool paused_) external {\\n ensureAllowed(\\\"_setActionsPaused(address[],uint8[],bool)\\\");\\n\\n uint256 numMarkets = markets_.length;\\n uint256 numActions = actions_.length;\\n for (uint256 marketIdx; marketIdx < numMarkets; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < numActions; ++actionIdx) {\\n setActionPausedInternal(markets_[marketIdx], actions_[actionIdx], paused_);\\n }\\n }\\n }\\n\\n /**\\n * @dev Pause/unpause an action on a market\\n * @param market Market to pause/unpause the action on\\n * @param action Action id to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n */\\n function setActionPausedInternal(address market, Action action, bool paused) internal {\\n ensureListed(markets[market]);\\n _actionPaused[market][uint256(action)] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @notice Sets a new VAI controller\\n * @dev Admin function to set a new VAI controller\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setVAIController(\\n VAIControllerInterface vaiController_\\n ) external compareAddress(address(vaiController), address(vaiController_)) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(address(vaiController_));\\n\\n VAIControllerInterface oldVaiController = vaiController;\\n vaiController = vaiController_;\\n emit NewVAIController(oldVaiController, vaiController_);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the VAI mint rate\\n * @param newVAIMintRate The new VAI mint rate to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setVAIMintRate(\\n uint256 newVAIMintRate\\n ) external compareValue(vaiMintRate, newVAIMintRate) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n uint256 oldVAIMintRate = vaiMintRate;\\n vaiMintRate = newVAIMintRate;\\n emit NewVAIMintRate(oldVAIMintRate, newVAIMintRate);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the minted VAI amount of the `owner`\\n * @param owner The address of the account to set\\n * @param amount The amount of VAI to set to the account\\n * @return The number of minted VAI by `owner`\\n */\\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256) {\\n checkProtocolPauseState();\\n\\n // Pausing is a very serious situation - we revert to sound the alarms\\n require(!mintVAIGuardianPaused && !repayVAIGuardianPaused, \\\"VAI is paused\\\");\\n // Check caller is vaiController\\n if (msg.sender != address(vaiController)) {\\n return fail(Error.REJECTION, FailureInfo.SET_MINTED_VAI_REJECTION);\\n }\\n mintedVAIs[owner] = amount;\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the treasury data.\\n * @param newTreasuryGuardian The new address of the treasury guardian to be set\\n * @param newTreasuryAddress The new address of the treasury to be set\\n * @param newTreasuryPercent The new treasury percent to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setTreasuryData(\\n address newTreasuryGuardian,\\n address newTreasuryAddress,\\n uint256 newTreasuryPercent\\n ) external returns (uint256) {\\n // Check caller is admin\\n ensureAdminOr(treasuryGuardian);\\n\\n require(newTreasuryPercent < 1e18, \\\"percent >= 100%\\\");\\n ensureNonzeroAddress(newTreasuryGuardian);\\n ensureNonzeroAddress(newTreasuryAddress);\\n\\n address oldTreasuryGuardian = treasuryGuardian;\\n address oldTreasuryAddress = treasuryAddress;\\n uint256 oldTreasuryPercent = treasuryPercent;\\n\\n treasuryGuardian = newTreasuryGuardian;\\n treasuryAddress = newTreasuryAddress;\\n treasuryPercent = newTreasuryPercent;\\n\\n emit NewTreasuryGuardian(oldTreasuryGuardian, newTreasuryGuardian);\\n emit NewTreasuryAddress(oldTreasuryAddress, newTreasuryAddress);\\n emit NewTreasuryPercent(oldTreasuryPercent, newTreasuryPercent);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /*** Venus Distribution ***/\\n\\n /**\\n * @dev Set ComptrollerLens contract address\\n * @param comptrollerLens_ The new ComptrollerLens contract address to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setComptrollerLens(\\n ComptrollerLensInterface comptrollerLens_\\n ) external compareAddress(address(comptrollerLens), address(comptrollerLens_)) returns (uint256) {\\n ensureAdmin();\\n ensureNonzeroAddress(address(comptrollerLens_));\\n address oldComptrollerLens = address(comptrollerLens);\\n comptrollerLens = comptrollerLens_;\\n emit NewComptrollerLens(oldComptrollerLens, address(comptrollerLens));\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the amount of XVS distributed per block to VAI Vault\\n * @param venusVAIVaultRate_ The amount of XVS wei per block to distribute to VAI Vault\\n */\\n function _setVenusVAIVaultRate(\\n uint256 venusVAIVaultRate_\\n ) external compareValue(venusVAIVaultRate, venusVAIVaultRate_) {\\n ensureAdmin();\\n if (vaiVaultAddress != address(0)) {\\n releaseToVault();\\n }\\n uint256 oldVenusVAIVaultRate = venusVAIVaultRate;\\n venusVAIVaultRate = venusVAIVaultRate_;\\n emit NewVenusVAIVaultRate(oldVenusVAIVaultRate, venusVAIVaultRate_);\\n }\\n\\n /**\\n * @notice Set the VAI Vault infos\\n * @param vault_ The address of the VAI Vault\\n * @param releaseStartBlock_ The start block of release to VAI Vault\\n * @param minReleaseAmount_ The minimum release amount to VAI Vault\\n */\\n function _setVAIVaultInfo(\\n address vault_,\\n uint256 releaseStartBlock_,\\n uint256 minReleaseAmount_\\n ) external compareAddress(vaiVaultAddress, vault_) {\\n ensureAdmin();\\n ensureNonzeroAddress(vault_);\\n if (vaiVaultAddress != address(0)) {\\n releaseToVault();\\n }\\n\\n vaiVaultAddress = vault_;\\n releaseStartBlock = releaseStartBlock_;\\n minReleaseAmount = minReleaseAmount_;\\n emit NewVAIVaultInfo(vault_, releaseStartBlock_, minReleaseAmount_);\\n }\\n\\n /**\\n * @notice Sets the prime token contract for the comptroller\\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setPrimeToken(IPrime _prime) external returns (uint) {\\n ensureAdmin();\\n ensureNonzeroAddress(address(_prime));\\n\\n IPrime oldPrime = prime;\\n prime = _prime;\\n emit NewPrimeToken(oldPrime, _prime);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /** @notice Enables forced liquidations for a market. If forced liquidation is enabled,\\n * borrows in the market may be liquidated regardless of the account liquidity\\n * @dev Allows a privileged role to set enable/disable forced liquidations\\n * @param vTokenBorrowed Borrowed vToken\\n * @param enable Whether to enable forced liquidations\\n */\\n function _setForcedLiquidation(address vTokenBorrowed, bool enable) external {\\n ensureAllowed(\\\"_setForcedLiquidation(address,bool)\\\");\\n if (vTokenBorrowed != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n isForcedLiquidationEnabled[vTokenBorrowed] = enable;\\n emit IsForcedLiquidationEnabledUpdated(vTokenBorrowed, enable);\\n }\\n\\n /**\\n * @notice Enables forced liquidations for user's borrows in a certain market. If forced\\n * liquidation is enabled, user's borrows in the market may be liquidated regardless of\\n * the account liquidity. Forced liquidation may be enabled for a user even if it is not\\n * enabled for the entire market.\\n * @param borrower The address of the borrower\\n * @param vTokenBorrowed Borrowed vToken\\n * @param enable Whether to enable forced liquidations\\n */\\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external {\\n ensureAllowed(\\\"_setForcedLiquidationForUser(address,address,bool)\\\");\\n if (vTokenBorrowed != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed] = enable;\\n emit IsForcedLiquidationEnabledForUserUpdated(borrower, vTokenBorrowed, enable);\\n }\\n\\n /**\\n * @notice Set the address of the XVS token\\n * @param xvs_ The address of the XVS token\\n */\\n function _setXVSToken(address xvs_) external {\\n ensureAdmin();\\n ensureNonzeroAddress(xvs_);\\n\\n emit NewXVSToken(xvs, xvs_);\\n xvs = xvs_;\\n }\\n\\n /**\\n * @notice Set the address of the XVS vToken\\n * @param xvsVToken_ The address of the XVS vToken\\n */\\n function _setXVSVToken(address xvsVToken_) external {\\n ensureAdmin();\\n ensureNonzeroAddress(xvsVToken_);\\n\\n address underlying = VToken(xvsVToken_).underlying();\\n require(underlying == xvs, \\\"invalid xvs vtoken address\\\");\\n\\n emit NewXVSVToken(xvsVToken, xvsVToken_);\\n xvsVToken = xvsVToken_;\\n }\\n}\\n\",\"keccak256\":\"0xb40b72d16ab7fe6b247c6482893e93d7cf343b21cef7c066f48ef56bec42e192\"},\"contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { PriceOracle } from \\\"../../../Oracle/PriceOracle.sol\\\";\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { ComptrollerTypes } from \\\"../../ComptrollerStorage.sol\\\";\\nimport { VAIControllerInterface } from \\\"../../../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"../../../Comptroller/ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../../../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ISetterFacet {\\n function _setPriceOracle(PriceOracle newOracle) external returns (uint256);\\n\\n function _setCloseFactor(uint256 newCloseFactorMantissa) external returns (uint256);\\n\\n function _setAccessControl(address newAccessControlAddress) external returns (uint256);\\n\\n function _setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256);\\n\\n function _setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256);\\n\\n function _setLiquidatorContract(address newLiquidatorContract_) external;\\n\\n function _setPauseGuardian(address newPauseGuardian) external returns (uint256);\\n\\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external;\\n\\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external;\\n\\n function _setProtocolPaused(bool state) external returns (bool);\\n\\n function _setActionsPaused(\\n address[] calldata markets,\\n ComptrollerTypes.Action[] calldata actions,\\n bool paused\\n ) external;\\n\\n function _setVAIController(VAIControllerInterface vaiController_) external returns (uint256);\\n\\n function _setVAIMintRate(uint256 newVAIMintRate) external returns (uint256);\\n\\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256);\\n\\n function _setTreasuryData(\\n address newTreasuryGuardian,\\n address newTreasuryAddress,\\n uint256 newTreasuryPercent\\n ) external returns (uint256);\\n\\n function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint256);\\n\\n function _setVenusVAIVaultRate(uint256 venusVAIVaultRate_) external;\\n\\n function _setVAIVaultInfo(address vault_, uint256 releaseStartBlock_, uint256 minReleaseAmount_) external;\\n\\n function _setForcedLiquidation(address vToken, bool enable) external;\\n\\n function _setPrimeToken(IPrime _prime) external returns (uint);\\n\\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external;\\n\\n function _setXVSToken(address xvs_) external;\\n\\n function _setXVSVToken(address xvsVToken_) external;\\n}\\n\",\"keccak256\":\"0x8d1e48445f80aca8652555a50783e3fb908351040abf45a90f1ce557abcabede\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport { VTokenInterface } from \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function mintVAI(uint256 mintVAIAmount) external returns (uint256);\\n\\n function repayVAI(uint256 amount) external returns (uint256, uint256);\\n\\n function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256);\\n\\n function liquidateVAI(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint256, uint256);\\n\\n function getMintableVAI(address minter) external view returns (uint256, uint256);\\n\\n function getVAIAddress() external view returns (address);\\n\\n function getVAIRepayAmount(address account) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x1f020ff46cb0efa0ebf563f449fd4d8aa1c8b8ed53c46860d71a08548d7fdfaa\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK,\\n UNLIST_MARKET_NOT_LISTED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0x4f5a41ef380336395706659e2b8f315870dcf3d617ea6f81104424500b15b1ef\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506130ee806100206000396000f3fe608060405234801561001057600080fd5b50600436106103f15760003560e01c80637dc0d1d011610215578063bf32442d11610125578063e37d4b79116100b8578063f445d70311610087578063f445d70314610cdf578063f519fc3014610d0d578063f851a44014610d33578063fa6331d814610d3b578063fd51a3ad14610d43576103f1565b8063e37d4b7914610c56578063e4028eee14610c7c578063e85a296014610ca8578063e875544614610cd7576103f1565b8063d24febad116100f4578063d24febad14610be4578063d3270f9914610c1a578063dce1544914610c22578063dcfbc0c714610c4e576103f1565b8063bf32442d14610ba8578063c5b4db5514610bb0578063c5f956af14610bd4578063c7ee005e14610bdc576103f1565b80639bb27d62116101a8578063b8324c7c11610177578063b8324c7c14610afe578063bb82aa5e14610b4c578063bb85745014610b54578063bbb8864a14610b7a578063bec04f7214610ba0576103f1565b80639bb27d6214610aa25780639bf34cbb14610aaa5780639cfdd9e614610ad0578063b2eafc3914610af6576103f1565b8063919a3736116101e4578063919a373614610a465780639254f5e514610a6c5780639460c8b514610a7457806394b2294b14610a9a576103f1565b80637dc0d1d0146109aa5780638a7dc165146109b25780638c1ac18a146109d85780638e8f294b146109fe576103f1565b8063425fad581161031057806352d84d1e116102a3578063607ef6c111610272578063607ef6c1146108b75780636662c7c914610975578063719f701b14610992578063765513831461099a5780637d172bd5146109a2576103f1565b806352d84d1e1461082857806355ee1fe1146108455780635dd3fc9d1461086b5780635f5af1aa14610891576103f1565b80634ef233fc116102df5780634ef233fc146106f95780634fd42e171461071f57806351a485e41461073c578063522c656b146107fa576103f1565b8063425fad58146106915780634a584432146106995780634ada90af146106bf5780634e0853db146106c7576103f1565b806326782247116103885780632ec04124116103575780632ec0412414610621578063317b0b771461063e5780634088c73e1461065b57806341a18d2c14610663576103f1565b806326782247146105145780632a6a60651461051c5780632b5d790c1461053b5780632bc7e29e146105fb576103f1565b806310b98338116103c457806310b983381461046c57806317db2163146104ae57806321af4569146104e857806324a3d6221461050c576103f1565b806302c3bcbb146103f657806304ef9d581461042e57806308e0225c146104365780630db4b4e514610464575b600080fd5b61041c6004803603602081101561040c57600080fd5b50356001600160a01b0316610d6f565b60408051918252519081900360200190f35b61041c610d81565b61041c6004803603604081101561044c57600080fd5b506001600160a01b0381358116916020013516610d87565b61041c610da4565b61049a6004803603604081101561048257600080fd5b506001600160a01b0381358116916020013516610daa565b604080519115158252519081900360200190f35b6104e6600480360360608110156104c457600080fd5b506001600160a01b038135811691602081013590911690604001351515610dca565b005b6104f0610e8f565b604080516001600160a01b039092168252519081900360200190f35b6104f0610e9e565b6104f0610ead565b61049a6004803603602081101561053257600080fd5b50351515610ebc565b6104e66004803603606081101561055157600080fd5b810190602081018135600160201b81111561056b57600080fd5b82018360208201111561057d57600080fd5b803590602001918460208302840111600160201b8311171561059e57600080fd5b919390929091602081019035600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460208302840111600160201b831117156105ee57600080fd5b9193509150351515610f4e565b61041c6004803603602081101561061157600080fd5b50356001600160a01b0316610fea565b61041c6004803603602081101561063757600080fd5b5035610ffc565b61041c6004803603602081101561065457600080fd5b503561109e565b61049a6111c8565b61041c6004803603604081101561067957600080fd5b506001600160a01b03813581169160200135166111d1565b61049a6111ee565b61041c600480360360208110156106af57600080fd5b50356001600160a01b03166111fd565b61041c61120f565b6104e6600480360360608110156106dd57600080fd5b506001600160a01b038135169060208101359060400135611215565b6104e66004803603602081101561070f57600080fd5b50356001600160a01b03166112fa565b61041c6004803603602081101561073557600080fd5b5035611434565b6104e66004803603604081101561075257600080fd5b810190602081018135600160201b81111561076c57600080fd5b82018360208201111561077e57600080fd5b803590602001918460208302840111600160201b8311171561079f57600080fd5b919390929091602081019035600160201b8111156107bc57600080fd5b8201836020820111156107ce57600080fd5b803590602001918460208302840111600160201b831117156107ef57600080fd5b509092509050611538565b6104e66004803603604081101561081057600080fd5b506001600160a01b038135169060200135151561168b565b6104f06004803603602081101561083e57600080fd5b5035611742565b61041c6004803603602081101561085b57600080fd5b50356001600160a01b0316611769565b61041c6004803603602081101561088157600080fd5b50356001600160a01b0316611834565b61041c600480360360208110156108a757600080fd5b50356001600160a01b0316611846565b6104e6600480360360408110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460208302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460208302840111600160201b8311171561096a57600080fd5b509092509050611911565b6104e66004803603602081101561098b57600080fd5b5035611a5b565b61041c611b0c565b61049a611b12565b6104f0611b20565b6104f0611b2f565b61041c600480360360208110156109c857600080fd5b50356001600160a01b0316611b3e565b61049a600480360360208110156109ee57600080fd5b50356001600160a01b0316611b50565b610a2460048036036020811015610a1457600080fd5b50356001600160a01b0316611b65565b6040805193151584526020840192909252151582820152519081900360600190f35b6104e660048036036020811015610a5c57600080fd5b50356001600160a01b0316611b8b565b6104f0611bf8565b61041c60048036036020811015610a8a57600080fd5b50356001600160a01b0316611c07565b61041c611c82565b6104f0611c88565b61041c60048036036020811015610ac057600080fd5b50356001600160a01b0316611c97565b61041c60048036036020811015610ae657600080fd5b50356001600160a01b0316611d61565b6104f0611e2c565b610b2460048036036020811015610b1457600080fd5b50356001600160a01b0316611e3b565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104f0611e65565b6104e660048036036020811015610b6a57600080fd5b50356001600160a01b0316611e74565b61041c60048036036020811015610b9057600080fd5b50356001600160a01b0316611f3b565b61041c611f4d565b6104f0611f53565b610bb8611f62565b604080516001600160e01b039092168252519081900360200190f35b6104f0611f75565b6104f0611f84565b61041c60048036036060811015610bfa57600080fd5b506001600160a01b03813581169160208101359091169060400135611f93565b6104f0612112565b6104f060048036036040811015610c3857600080fd5b506001600160a01b038135169060200135612121565b6104f0612156565b610b2460048036036020811015610c6c57600080fd5b50356001600160a01b0316612165565b61041c60048036036040811015610c9257600080fd5b506001600160a01b03813516906020013561218f565b61049a60048036036040811015610cbe57600080fd5b5080356001600160a01b0316906020013560ff1661238d565b61041c6123cf565b61049a60048036036040811015610cf557600080fd5b506001600160a01b03813581169160200135166123d5565b61041c60048036036020811015610d2357600080fd5b50356001600160a01b03166123f5565b6104f06124c0565b61041c6124cf565b61041c60048036036040811015610d5957600080fd5b506001600160a01b0381351690602001356124d5565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b610deb604051806060016040528060328152602001612f3860329139612582565b6015546001600160a01b03838116911614610e21576001600160a01b0382166000908152600960205260409020610e21906126a6565b6001600160a01b03838116600081815260326020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fc080966e9e93529edc1b244180c245bc60f3d86f1e690a17651a5e428746a8cd9281900390910190a3505050565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b6000610efc6040518060400160405280601881526020017f5f73657450726f746f636f6c50617573656428626f6f6c290000000000000000815250612582565b6018805483151562010000810262ff0000199092169190911790915560408051918252517fd7500633dd3ddd74daa7af62f8c8404c7fe4a81da179998db851696bed004b389181900360200190a15090565b610f6f604051806060016040528060298152602001612f9460299139612582565b838260005b82811015610fe05760005b82811015610fd757610fcf898984818110610f9657fe5b905060200201356001600160a01b0316888884818110610fb257fe5b90506020020135600881118015610fc857600080fd5b50876126f0565b600101610f7f565b50600101610f74565b5050505050505050565b60166020526000908152604090205481565b60006017548280821415611045576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61104d6127a8565b6017805490859055604080518281526020810187905281517f73747d68b346dce1e932bcd238282e7ac84c01569e1f8d0469c222fdc6e9d5a4929181900390910190a160005b9350505b5050919050565b600060055482808214156110e7576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b6110ef6127a8565b6110f7612f24565b50604080516020810190915284815261110e612f24565b506040805160208101909152670c7d713b49da0000815261112d612f24565b50604080516020810190915266b1a2bc2ec50000815261114d82846127fa565b8061115d575061115d8184612801565b156111775761116d600580612808565b9550505050611097565b600580549088905560408051828152602081018a905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a1600098975050505050505050565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b601b546001600160a01b0390811690849081168214156112665760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b61126e6127a8565b6112778561286e565b601b546001600160a01b031615611290576112906128c1565b601b80546001600160a01b0319166001600160a01b038716908117909155601c859055601d849055604080518681526020810186905281517f7059037d74ee16b0fb06a4a30f3348dd2635f301f92e373c92899a25a522ef6e929181900390910190a25050505050565b6113026127a8565b61130b8161286e565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b50516033549091506001600160a01b038083169116146113d7576040805162461bcd60e51b815260206004820152601a60248201527f696e76616c6964207876732076746f6b656e2061646472657373000000000000604482015290519081900360640190fd5b6034546040516001600160a01b038085169216907f2565e1579c0926afb7113edbfd85373e85cadaa3e0346f04de19686a2bb86ed190600090a350603480546001600160a01b0319166001600160a01b0392909216919091179055565b6000600654828082141561147d576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61149e604051806060016040528060218152602001612fbd60219139612582565b670de0b6b3a76400008410156114ee576040805162461bcd60e51b815260206004820152601060248201526f0d2dcc6cadce8d2ecca40784062ca62760831b604482015290519081900360640190fd5b6006805490859055604080518281526020810187905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611093565b611559604051806060016040528060298152602001612fde60299139612582565b8281811580159061156957508082145b6115aa576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b82811015611682578484828181106115c157fe5b90506020020135602760008989858181106115d857fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000208190555086868281811061161857fe5b905060200201356001600160a01b03166001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f886868481811061165e57fe5b905060200201356040518082815260200191505060405180910390a26001016115ad565b50505050505050565b6116ac60405180606001604052806023815260200161300760239139612582565b6015546001600160a01b038381169116146116e2576001600160a01b03821660009081526009602052604090206116e2906126a6565b6001600160a01b0382166000818152602d6020908152604091829020805460ff1916851515908117909155825190815291517f03561d5280ebb02280893b1d60978e4a27e7654a149c5d0e7c2cf65389ce16949281900390910190a25050565b600d818154811061174f57fe5b6000918252602090912001546001600160a01b0316905081565b6004546000906001600160a01b0390811690839081168214156117bd5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6117c56127a8565b6117ce8461286e565b600480546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611093565b602b6020526000908152604090205481565b600a546000906001600160a01b03908116908390811682141561189a5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6118a26127a8565b6118ab8461286e565b600a80546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e929181900390910190a16000611093565b61193260405180606001604052806029815260200161302a60299139612582565b8281811580159061194257508082145b611983576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b828110156116825784848281811061199a57fe5b90506020020135601f60008989858181106119b157fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106119f157fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611a3757fe5b905060200201356040518082815260200191505060405180910390a2600101611986565b601a548180821415611aa2576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b611aaa6127a8565b601b546001600160a01b031615611ac357611ac36128c1565b601a805490849055604080518281526020810186905281517fe81d4ac15e5afa1e708e66664eddc697177423d950d133bda8262d8885e6da3b929181900390910190a150505050565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b611b936127a8565b611b9c8161286e565b6033546040516001600160a01b038084169216907ffe7fd0d872def0f65050e9f38fc6691d0c192c694a56f09b04bec5fb2ea61f2b90600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6015546001600160a01b031681565b6000611c116127a8565b611c1a8261286e565b603180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fcb20dab7409e4fb972d9adccb39530520b226ce6940d85c9523a499b950b6ea3929181900390910190a160009392505050565b60075481565b6025546001600160a01b031681565b6026546000906001600160a01b039081169083908116821415611ceb5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611cf36127a8565b611cfc8461286e565b602680546001600160a01b038681166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0f7eb572d1b3053a0a3a33c04151364cf88d163182a5e4e1088cb8e52321e08a9281900390910190a16000611093565b6015546000906001600160a01b039081169083908116821415611db55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611dbd6127a8565b611dc68461286e565b601580546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fe1ddcb2dab8e5b03cfc8c67a0d5861d91d16f7bd2612fd381faf4541d212c9b2929181900390910190a16000611093565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b6025546001600160a01b039081169082908116821415611ec55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611ecd6127a8565b611ed68361286e565b602580546001600160a01b038581166001600160a01b0319831681179093556040805191909216808252602082019390935281517fa5ea5616d5f6dbbaa62fdfcf3856723216eed485c394d9e51ec8e6d40e1d1ac1929181900390910190a150505050565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b602054600090611fab906001600160a01b0316612a88565b670de0b6b3a76400008210611ff9576040805162461bcd60e51b815260206004820152600f60248201526e70657263656e74203e3d203130302560881b604482015290519081900360640190fd5b6120028461286e565b61200b8361286e565b6020805460218054602280546001600160a01b038a81166001600160a01b0319808816821789558b8316908616179095559188905560408051958316808752968601949094528351929091169390927f29f06ea15931797ebaed313d81d100963dc22cb213cb4ce2737b5a62b1a8b1e892918290030190a1604080516001600160a01b0380851682528816602082015281517f8de763046d7b8f08b6c3d03543de1d615309417842bb5d2d62f110f65809ddac929181900390910190a1604080518281526020810187905281517f0893f8f4101baaabbeb513f96761e7a36eb837403c82cc651c292a4abdc94ed7929181900390910190a1600093505050505b9392505050565b6026546001600160a01b031681565b6008602052816000526040600020818154811061213a57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526009602052604081206001015482808214156121ef576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61221060405180606001604052806025815260200161309560259139612582565b6122198561286e565b6001600160a01b038516600090815260096020526040902061223a816126a6565b612242612f24565b506040805160208101909152858152612259612f24565b506040805160208101909152670c7d713b49da0000815261227a81836127fa565b156122955761228b60066008612808565b9550505050612385565b861580159061231e5750600480546040805163fc57d4df60e01b81526001600160a01b038c8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d602081101561231a57600080fd5b5051155b1561232f5761228b600d6009612808565b6001830180549088905560408051828152602081018a905281516001600160a01b038c16927f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5928290030190a260009650505050505b505092915050565b6001600160a01b0382166000908152602960205260408120818360088111156123b257fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b603260209081526000928352604080842090915290825290205460ff1681565b6028546000906001600160a01b0390811690839081168214156124495760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6124516127a8565b61245a8461286e565b602880546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0f1eca7612e020f6e4582bcead0573eba4b5f7b56668754c6aed82ef12057dd4929181900390910190a16000611093565b6000546001600160a01b031681565b601a5481565b60006124df612aea565b60185460ff161580156124fa5750601854610100900460ff16155b61253b576040805162461bcd60e51b815260206004820152600d60248201526c159052481a5cc81c185d5cd959609a1b604482015290519081900360640190fd5b6015546001600160a01b0316331461256057612559600e6016612808565b90506123c9565b6001600160a01b03831660009081526016602052604081208390559392505050565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156125eb5781810151838201526020016125d3565b50505050905090810190601f1680156126185780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561263657600080fd5b505afa15801561264a573d6000803e3d6000fd5b505050506040513d602081101561266057600080fd5b50516126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b805460ff166126a3576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612711906126a6565b6001600160a01b0383166000908152602960205260408120829184600881111561273757fe5b81526020810191909152604001600020805460ff191691151591909117905581600881111561276257fe5b60408051831515815290516001600160a01b038616917f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d919081900360200190a3505050565b6000546001600160a01b031633146127f8576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b565b5190511090565b5190511190565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601381111561283757fe5b83601881111561284357fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561210b57fe5b6001600160a01b0381166126a3576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b601c5415806128d85750601c546128d6612b3d565b105b156128e2576127f8565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561293257600080fd5b505afa158015612946573d6000803e3d6000fd5b505050506040513d602081101561295c57600080fd5b505190508061296c5750506127f8565b60008061298261297a612b3d565b601c54612b41565b90506000612992601a5483612b7b565b90508084106129a3578092506129a7565b8392505b601d548310156129bb5750505050506127f8565b6129c3612b3d565b601c55601b546129e6906001600160a01b0387811691168563ffffffff612bbd16565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a6957600080fd5b505af1158015612a7d573d6000803e3d6000fd5b505050505050505050565b6000546001600160a01b0316331480612aa95750336001600160a01b038216145b6126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b60185462010000900460ff16156127f8576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b4390565b600061210b8383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250612c14565b600061210b83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250612cab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612c0f908490612d2a565b505050565b60008184841115612ca35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c68578181015183820152602001612c50565b50505050905090810190601f168015612c955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000831580612cb8575082155b15612cc55750600061210b565b83830283858281612cd257fe5b04148390612d215760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c68578181015183820152602001612c50565b50949350505050565b612d3c826001600160a01b0316612ee8565b612d8d576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612dcb5780518252601f199092019160209182019101612dac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612e2d576040519150601f19603f3d011682016040523d82523d6000602084013e612e32565b606091505b509150915081612e89576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115612ee257808060200190516020811015612ea557600080fd5b5051612ee25760405162461bcd60e51b815260040180806020018281038252602a815260200180612f6a602a913960400191505060405180910390fd5b50505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612f1c57508115155b949350505050565b604051806020016040528060008152509056fe5f736574466f726365644c69717569646174696f6e466f725573657228616464726573732c616464726573732c626f6f6c295361666542455032303a204245503230206f7065726174696f6e20646964206e6f7420737563636565645f736574416374696f6e7350617573656428616464726573735b5d2c75696e74385b5d2c626f6f6c295f7365744c69717569646174696f6e496e63656e746976652875696e74323536295f7365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d295f736574466f726365644c69717569646174696f6e28616464726573732c626f6f6c295f7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d296f6c642076616c75652069732073616d65206173206e65772076616c756500006f6c6420616464726573732069732073616d65206173206e657720616464726573735f736574436f6c6c61746572616c466163746f7228616464726573732c75696e7432353629a265627a7a7231582077590d2a11f73c0c0e36d7c0200cb6249886b0adc220f0460efe3b2556a4de9264736f6c63430005100032", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103f15760003560e01c80637dc0d1d011610215578063bf32442d11610125578063e37d4b79116100b8578063f445d70311610087578063f445d70314610cdf578063f519fc3014610d0d578063f851a44014610d33578063fa6331d814610d3b578063fd51a3ad14610d43576103f1565b8063e37d4b7914610c56578063e4028eee14610c7c578063e85a296014610ca8578063e875544614610cd7576103f1565b8063d24febad116100f4578063d24febad14610be4578063d3270f9914610c1a578063dce1544914610c22578063dcfbc0c714610c4e576103f1565b8063bf32442d14610ba8578063c5b4db5514610bb0578063c5f956af14610bd4578063c7ee005e14610bdc576103f1565b80639bb27d62116101a8578063b8324c7c11610177578063b8324c7c14610afe578063bb82aa5e14610b4c578063bb85745014610b54578063bbb8864a14610b7a578063bec04f7214610ba0576103f1565b80639bb27d6214610aa25780639bf34cbb14610aaa5780639cfdd9e614610ad0578063b2eafc3914610af6576103f1565b8063919a3736116101e4578063919a373614610a465780639254f5e514610a6c5780639460c8b514610a7457806394b2294b14610a9a576103f1565b80637dc0d1d0146109aa5780638a7dc165146109b25780638c1ac18a146109d85780638e8f294b146109fe576103f1565b8063425fad581161031057806352d84d1e116102a3578063607ef6c111610272578063607ef6c1146108b75780636662c7c914610975578063719f701b14610992578063765513831461099a5780637d172bd5146109a2576103f1565b806352d84d1e1461082857806355ee1fe1146108455780635dd3fc9d1461086b5780635f5af1aa14610891576103f1565b80634ef233fc116102df5780634ef233fc146106f95780634fd42e171461071f57806351a485e41461073c578063522c656b146107fa576103f1565b8063425fad58146106915780634a584432146106995780634ada90af146106bf5780634e0853db146106c7576103f1565b806326782247116103885780632ec04124116103575780632ec0412414610621578063317b0b771461063e5780634088c73e1461065b57806341a18d2c14610663576103f1565b806326782247146105145780632a6a60651461051c5780632b5d790c1461053b5780632bc7e29e146105fb576103f1565b806310b98338116103c457806310b983381461046c57806317db2163146104ae57806321af4569146104e857806324a3d6221461050c576103f1565b806302c3bcbb146103f657806304ef9d581461042e57806308e0225c146104365780630db4b4e514610464575b600080fd5b61041c6004803603602081101561040c57600080fd5b50356001600160a01b0316610d6f565b60408051918252519081900360200190f35b61041c610d81565b61041c6004803603604081101561044c57600080fd5b506001600160a01b0381358116916020013516610d87565b61041c610da4565b61049a6004803603604081101561048257600080fd5b506001600160a01b0381358116916020013516610daa565b604080519115158252519081900360200190f35b6104e6600480360360608110156104c457600080fd5b506001600160a01b038135811691602081013590911690604001351515610dca565b005b6104f0610e8f565b604080516001600160a01b039092168252519081900360200190f35b6104f0610e9e565b6104f0610ead565b61049a6004803603602081101561053257600080fd5b50351515610ebc565b6104e66004803603606081101561055157600080fd5b810190602081018135600160201b81111561056b57600080fd5b82018360208201111561057d57600080fd5b803590602001918460208302840111600160201b8311171561059e57600080fd5b919390929091602081019035600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460208302840111600160201b831117156105ee57600080fd5b9193509150351515610f4e565b61041c6004803603602081101561061157600080fd5b50356001600160a01b0316610fea565b61041c6004803603602081101561063757600080fd5b5035610ffc565b61041c6004803603602081101561065457600080fd5b503561109e565b61049a6111c8565b61041c6004803603604081101561067957600080fd5b506001600160a01b03813581169160200135166111d1565b61049a6111ee565b61041c600480360360208110156106af57600080fd5b50356001600160a01b03166111fd565b61041c61120f565b6104e6600480360360608110156106dd57600080fd5b506001600160a01b038135169060208101359060400135611215565b6104e66004803603602081101561070f57600080fd5b50356001600160a01b03166112fa565b61041c6004803603602081101561073557600080fd5b5035611434565b6104e66004803603604081101561075257600080fd5b810190602081018135600160201b81111561076c57600080fd5b82018360208201111561077e57600080fd5b803590602001918460208302840111600160201b8311171561079f57600080fd5b919390929091602081019035600160201b8111156107bc57600080fd5b8201836020820111156107ce57600080fd5b803590602001918460208302840111600160201b831117156107ef57600080fd5b509092509050611538565b6104e66004803603604081101561081057600080fd5b506001600160a01b038135169060200135151561168b565b6104f06004803603602081101561083e57600080fd5b5035611742565b61041c6004803603602081101561085b57600080fd5b50356001600160a01b0316611769565b61041c6004803603602081101561088157600080fd5b50356001600160a01b0316611834565b61041c600480360360208110156108a757600080fd5b50356001600160a01b0316611846565b6104e6600480360360408110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460208302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460208302840111600160201b8311171561096a57600080fd5b509092509050611911565b6104e66004803603602081101561098b57600080fd5b5035611a5b565b61041c611b0c565b61049a611b12565b6104f0611b20565b6104f0611b2f565b61041c600480360360208110156109c857600080fd5b50356001600160a01b0316611b3e565b61049a600480360360208110156109ee57600080fd5b50356001600160a01b0316611b50565b610a2460048036036020811015610a1457600080fd5b50356001600160a01b0316611b65565b6040805193151584526020840192909252151582820152519081900360600190f35b6104e660048036036020811015610a5c57600080fd5b50356001600160a01b0316611b8b565b6104f0611bf8565b61041c60048036036020811015610a8a57600080fd5b50356001600160a01b0316611c07565b61041c611c82565b6104f0611c88565b61041c60048036036020811015610ac057600080fd5b50356001600160a01b0316611c97565b61041c60048036036020811015610ae657600080fd5b50356001600160a01b0316611d61565b6104f0611e2c565b610b2460048036036020811015610b1457600080fd5b50356001600160a01b0316611e3b565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104f0611e65565b6104e660048036036020811015610b6a57600080fd5b50356001600160a01b0316611e74565b61041c60048036036020811015610b9057600080fd5b50356001600160a01b0316611f3b565b61041c611f4d565b6104f0611f53565b610bb8611f62565b604080516001600160e01b039092168252519081900360200190f35b6104f0611f75565b6104f0611f84565b61041c60048036036060811015610bfa57600080fd5b506001600160a01b03813581169160208101359091169060400135611f93565b6104f0612112565b6104f060048036036040811015610c3857600080fd5b506001600160a01b038135169060200135612121565b6104f0612156565b610b2460048036036020811015610c6c57600080fd5b50356001600160a01b0316612165565b61041c60048036036040811015610c9257600080fd5b506001600160a01b03813516906020013561218f565b61049a60048036036040811015610cbe57600080fd5b5080356001600160a01b0316906020013560ff1661238d565b61041c6123cf565b61049a60048036036040811015610cf557600080fd5b506001600160a01b03813581169160200135166123d5565b61041c60048036036020811015610d2357600080fd5b50356001600160a01b03166123f5565b6104f06124c0565b61041c6124cf565b61041c60048036036040811015610d5957600080fd5b506001600160a01b0381351690602001356124d5565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b610deb604051806060016040528060328152602001612f3860329139612582565b6015546001600160a01b03838116911614610e21576001600160a01b0382166000908152600960205260409020610e21906126a6565b6001600160a01b03838116600081815260326020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fc080966e9e93529edc1b244180c245bc60f3d86f1e690a17651a5e428746a8cd9281900390910190a3505050565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b6000610efc6040518060400160405280601881526020017f5f73657450726f746f636f6c50617573656428626f6f6c290000000000000000815250612582565b6018805483151562010000810262ff0000199092169190911790915560408051918252517fd7500633dd3ddd74daa7af62f8c8404c7fe4a81da179998db851696bed004b389181900360200190a15090565b610f6f604051806060016040528060298152602001612f9460299139612582565b838260005b82811015610fe05760005b82811015610fd757610fcf898984818110610f9657fe5b905060200201356001600160a01b0316888884818110610fb257fe5b90506020020135600881118015610fc857600080fd5b50876126f0565b600101610f7f565b50600101610f74565b5050505050505050565b60166020526000908152604090205481565b60006017548280821415611045576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61104d6127a8565b6017805490859055604080518281526020810187905281517f73747d68b346dce1e932bcd238282e7ac84c01569e1f8d0469c222fdc6e9d5a4929181900390910190a160005b9350505b5050919050565b600060055482808214156110e7576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b6110ef6127a8565b6110f7612f24565b50604080516020810190915284815261110e612f24565b506040805160208101909152670c7d713b49da0000815261112d612f24565b50604080516020810190915266b1a2bc2ec50000815261114d82846127fa565b8061115d575061115d8184612801565b156111775761116d600580612808565b9550505050611097565b600580549088905560408051828152602081018a905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a1600098975050505050505050565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b601b546001600160a01b0390811690849081168214156112665760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b61126e6127a8565b6112778561286e565b601b546001600160a01b031615611290576112906128c1565b601b80546001600160a01b0319166001600160a01b038716908117909155601c859055601d849055604080518681526020810186905281517f7059037d74ee16b0fb06a4a30f3348dd2635f301f92e373c92899a25a522ef6e929181900390910190a25050505050565b6113026127a8565b61130b8161286e565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b50516033549091506001600160a01b038083169116146113d7576040805162461bcd60e51b815260206004820152601a60248201527f696e76616c6964207876732076746f6b656e2061646472657373000000000000604482015290519081900360640190fd5b6034546040516001600160a01b038085169216907f2565e1579c0926afb7113edbfd85373e85cadaa3e0346f04de19686a2bb86ed190600090a350603480546001600160a01b0319166001600160a01b0392909216919091179055565b6000600654828082141561147d576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61149e604051806060016040528060218152602001612fbd60219139612582565b670de0b6b3a76400008410156114ee576040805162461bcd60e51b815260206004820152601060248201526f0d2dcc6cadce8d2ecca40784062ca62760831b604482015290519081900360640190fd5b6006805490859055604080518281526020810187905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611093565b611559604051806060016040528060298152602001612fde60299139612582565b8281811580159061156957508082145b6115aa576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b82811015611682578484828181106115c157fe5b90506020020135602760008989858181106115d857fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000208190555086868281811061161857fe5b905060200201356001600160a01b03166001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f886868481811061165e57fe5b905060200201356040518082815260200191505060405180910390a26001016115ad565b50505050505050565b6116ac60405180606001604052806023815260200161300760239139612582565b6015546001600160a01b038381169116146116e2576001600160a01b03821660009081526009602052604090206116e2906126a6565b6001600160a01b0382166000818152602d6020908152604091829020805460ff1916851515908117909155825190815291517f03561d5280ebb02280893b1d60978e4a27e7654a149c5d0e7c2cf65389ce16949281900390910190a25050565b600d818154811061174f57fe5b6000918252602090912001546001600160a01b0316905081565b6004546000906001600160a01b0390811690839081168214156117bd5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6117c56127a8565b6117ce8461286e565b600480546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611093565b602b6020526000908152604090205481565b600a546000906001600160a01b03908116908390811682141561189a5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6118a26127a8565b6118ab8461286e565b600a80546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e929181900390910190a16000611093565b61193260405180606001604052806029815260200161302a60299139612582565b8281811580159061194257508082145b611983576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b828110156116825784848281811061199a57fe5b90506020020135601f60008989858181106119b157fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106119f157fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611a3757fe5b905060200201356040518082815260200191505060405180910390a2600101611986565b601a548180821415611aa2576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b611aaa6127a8565b601b546001600160a01b031615611ac357611ac36128c1565b601a805490849055604080518281526020810186905281517fe81d4ac15e5afa1e708e66664eddc697177423d950d133bda8262d8885e6da3b929181900390910190a150505050565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b611b936127a8565b611b9c8161286e565b6033546040516001600160a01b038084169216907ffe7fd0d872def0f65050e9f38fc6691d0c192c694a56f09b04bec5fb2ea61f2b90600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6015546001600160a01b031681565b6000611c116127a8565b611c1a8261286e565b603180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fcb20dab7409e4fb972d9adccb39530520b226ce6940d85c9523a499b950b6ea3929181900390910190a160009392505050565b60075481565b6025546001600160a01b031681565b6026546000906001600160a01b039081169083908116821415611ceb5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611cf36127a8565b611cfc8461286e565b602680546001600160a01b038681166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0f7eb572d1b3053a0a3a33c04151364cf88d163182a5e4e1088cb8e52321e08a9281900390910190a16000611093565b6015546000906001600160a01b039081169083908116821415611db55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611dbd6127a8565b611dc68461286e565b601580546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fe1ddcb2dab8e5b03cfc8c67a0d5861d91d16f7bd2612fd381faf4541d212c9b2929181900390910190a16000611093565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b6025546001600160a01b039081169082908116821415611ec55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611ecd6127a8565b611ed68361286e565b602580546001600160a01b038581166001600160a01b0319831681179093556040805191909216808252602082019390935281517fa5ea5616d5f6dbbaa62fdfcf3856723216eed485c394d9e51ec8e6d40e1d1ac1929181900390910190a150505050565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b602054600090611fab906001600160a01b0316612a88565b670de0b6b3a76400008210611ff9576040805162461bcd60e51b815260206004820152600f60248201526e70657263656e74203e3d203130302560881b604482015290519081900360640190fd5b6120028461286e565b61200b8361286e565b6020805460218054602280546001600160a01b038a81166001600160a01b0319808816821789558b8316908616179095559188905560408051958316808752968601949094528351929091169390927f29f06ea15931797ebaed313d81d100963dc22cb213cb4ce2737b5a62b1a8b1e892918290030190a1604080516001600160a01b0380851682528816602082015281517f8de763046d7b8f08b6c3d03543de1d615309417842bb5d2d62f110f65809ddac929181900390910190a1604080518281526020810187905281517f0893f8f4101baaabbeb513f96761e7a36eb837403c82cc651c292a4abdc94ed7929181900390910190a1600093505050505b9392505050565b6026546001600160a01b031681565b6008602052816000526040600020818154811061213a57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526009602052604081206001015482808214156121ef576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61221060405180606001604052806025815260200161309560259139612582565b6122198561286e565b6001600160a01b038516600090815260096020526040902061223a816126a6565b612242612f24565b506040805160208101909152858152612259612f24565b506040805160208101909152670c7d713b49da0000815261227a81836127fa565b156122955761228b60066008612808565b9550505050612385565b861580159061231e5750600480546040805163fc57d4df60e01b81526001600160a01b038c8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d602081101561231a57600080fd5b5051155b1561232f5761228b600d6009612808565b6001830180549088905560408051828152602081018a905281516001600160a01b038c16927f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5928290030190a260009650505050505b505092915050565b6001600160a01b0382166000908152602960205260408120818360088111156123b257fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b603260209081526000928352604080842090915290825290205460ff1681565b6028546000906001600160a01b0390811690839081168214156124495760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6124516127a8565b61245a8461286e565b602880546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0f1eca7612e020f6e4582bcead0573eba4b5f7b56668754c6aed82ef12057dd4929181900390910190a16000611093565b6000546001600160a01b031681565b601a5481565b60006124df612aea565b60185460ff161580156124fa5750601854610100900460ff16155b61253b576040805162461bcd60e51b815260206004820152600d60248201526c159052481a5cc81c185d5cd959609a1b604482015290519081900360640190fd5b6015546001600160a01b0316331461256057612559600e6016612808565b90506123c9565b6001600160a01b03831660009081526016602052604081208390559392505050565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156125eb5781810151838201526020016125d3565b50505050905090810190601f1680156126185780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561263657600080fd5b505afa15801561264a573d6000803e3d6000fd5b505050506040513d602081101561266057600080fd5b50516126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b805460ff166126a3576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612711906126a6565b6001600160a01b0383166000908152602960205260408120829184600881111561273757fe5b81526020810191909152604001600020805460ff191691151591909117905581600881111561276257fe5b60408051831515815290516001600160a01b038616917f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d919081900360200190a3505050565b6000546001600160a01b031633146127f8576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b565b5190511090565b5190511190565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601381111561283757fe5b83601881111561284357fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561210b57fe5b6001600160a01b0381166126a3576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b601c5415806128d85750601c546128d6612b3d565b105b156128e2576127f8565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561293257600080fd5b505afa158015612946573d6000803e3d6000fd5b505050506040513d602081101561295c57600080fd5b505190508061296c5750506127f8565b60008061298261297a612b3d565b601c54612b41565b90506000612992601a5483612b7b565b90508084106129a3578092506129a7565b8392505b601d548310156129bb5750505050506127f8565b6129c3612b3d565b601c55601b546129e6906001600160a01b0387811691168563ffffffff612bbd16565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a6957600080fd5b505af1158015612a7d573d6000803e3d6000fd5b505050505050505050565b6000546001600160a01b0316331480612aa95750336001600160a01b038216145b6126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b60185462010000900460ff16156127f8576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b4390565b600061210b8383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250612c14565b600061210b83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250612cab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612c0f908490612d2a565b505050565b60008184841115612ca35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c68578181015183820152602001612c50565b50505050905090810190601f168015612c955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000831580612cb8575082155b15612cc55750600061210b565b83830283858281612cd257fe5b04148390612d215760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c68578181015183820152602001612c50565b50949350505050565b612d3c826001600160a01b0316612ee8565b612d8d576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612dcb5780518252601f199092019160209182019101612dac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612e2d576040519150601f19603f3d011682016040523d82523d6000602084013e612e32565b606091505b509150915081612e89576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115612ee257808060200190516020811015612ea557600080fd5b5051612ee25760405162461bcd60e51b815260040180806020018281038252602a815260200180612f6a602a913960400191505060405180910390fd5b50505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612f1c57508115155b949350505050565b604051806020016040528060008152509056fe5f736574466f726365644c69717569646174696f6e466f725573657228616464726573732c616464726573732c626f6f6c295361666542455032303a204245503230206f7065726174696f6e20646964206e6f7420737563636565645f736574416374696f6e7350617573656428616464726573735b5d2c75696e74385b5d2c626f6f6c295f7365744c69717569646174696f6e496e63656e746976652875696e74323536295f7365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d295f736574466f726365644c69717569646174696f6e28616464726573732c626f6f6c295f7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d296f6c642076616c75652069732073616d65206173206e65772076616c756500006f6c6420616464726573732069732073616d65206173206e657720616464726573735f736574436f6c6c61746572616c466163746f7228616464726573732c75696e7432353629a265627a7a7231582077590d2a11f73c0c0e36d7c0200cb6249886b0adc220f0460efe3b2556a4de9264736f6c63430005100032", "devdoc": { "author": "Venus", "details": "This facet contains all the setters for the states", @@ -1924,9 +1924,9 @@ } }, "_setMarketBorrowCaps(address[],uint256[])": { - "details": "Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to unlimited borrowing", + "details": "Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed", "params": { - "newBorrowCaps": "The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing", + "newBorrowCaps": "The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed", "vTokens": "The addresses of the markets (tokens) to change the borrow caps for" } }, @@ -2097,7 +2097,7 @@ "storageLayout": { "storage": [ { - "astId": 2402, + "astId": 2503, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "admin", "offset": 0, @@ -2105,7 +2105,7 @@ "type": "t_address" }, { - "astId": 2404, + "astId": 2505, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "pendingAdmin", "offset": 0, @@ -2113,7 +2113,7 @@ "type": "t_address" }, { - "astId": 2406, + "astId": 2507, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "comptrollerImplementation", "offset": 0, @@ -2121,7 +2121,7 @@ "type": "t_address" }, { - "astId": 2408, + "astId": 2509, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "pendingComptrollerImplementation", "offset": 0, @@ -2129,15 +2129,15 @@ "type": "t_address" }, { - "astId": 2415, + "astId": 2516, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "oracle", "offset": 0, "slot": "4", - "type": "t_contract(PriceOracle)12106" + "type": "t_contract(PriceOracle)12346" }, { - "astId": 2417, + "astId": 2518, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "closeFactorMantissa", "offset": 0, @@ -2145,7 +2145,7 @@ "type": "t_uint256" }, { - "astId": 2419, + "astId": 2520, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "liquidationIncentiveMantissa", "offset": 0, @@ -2153,7 +2153,7 @@ "type": "t_uint256" }, { - "astId": 2421, + "astId": 2522, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "maxAssets", "offset": 0, @@ -2161,23 +2161,23 @@ "type": "t_uint256" }, { - "astId": 2426, + "astId": 2527, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "accountAssets", "offset": 0, "slot": "8", - "type": "t_mapping(t_address,t_array(t_contract(VToken)23033)dyn_storage)" + "type": "t_mapping(t_address,t_array(t_contract(VToken)23484)dyn_storage)" }, { - "astId": 2441, + "astId": 2542, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "markets", "offset": 0, "slot": "9", - "type": "t_mapping(t_address,t_struct(Market)2437_storage)" + "type": "t_mapping(t_address,t_struct(Market)2538_storage)" }, { - "astId": 2443, + "astId": 2544, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "pauseGuardian", "offset": 0, @@ -2185,7 +2185,7 @@ "type": "t_address" }, { - "astId": 2445, + "astId": 2546, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_mintGuardianPaused", "offset": 20, @@ -2193,7 +2193,7 @@ "type": "t_bool" }, { - "astId": 2447, + "astId": 2548, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_borrowGuardianPaused", "offset": 21, @@ -2201,7 +2201,7 @@ "type": "t_bool" }, { - "astId": 2449, + "astId": 2550, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "transferGuardianPaused", "offset": 22, @@ -2209,7 +2209,7 @@ "type": "t_bool" }, { - "astId": 2451, + "astId": 2552, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "seizeGuardianPaused", "offset": 23, @@ -2217,7 +2217,7 @@ "type": "t_bool" }, { - "astId": 2455, + "astId": 2556, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "mintGuardianPaused", "offset": 0, @@ -2225,7 +2225,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2459, + "astId": 2560, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "borrowGuardianPaused", "offset": 0, @@ -2233,15 +2233,15 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2467, + "astId": 2568, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "allMarkets", "offset": 0, "slot": "13", - "type": "t_array(t_contract(VToken)23033)dyn_storage" + "type": "t_array(t_contract(VToken)23484)dyn_storage" }, { - "astId": 2469, + "astId": 2570, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusRate", "offset": 0, @@ -2249,7 +2249,7 @@ "type": "t_uint256" }, { - "astId": 2473, + "astId": 2574, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusSpeeds", "offset": 0, @@ -2257,23 +2257,23 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2477, + "astId": 2578, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusSupplyState", "offset": 0, "slot": "16", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)" }, { - "astId": 2481, + "astId": 2582, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusBorrowState", "offset": 0, "slot": "17", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)" }, { - "astId": 2487, + "astId": 2588, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusSupplierIndex", "offset": 0, @@ -2281,7 +2281,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2493, + "astId": 2594, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusBorrowerIndex", "offset": 0, @@ -2289,7 +2289,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2497, + "astId": 2598, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusAccrued", "offset": 0, @@ -2297,15 +2297,15 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2499, + "astId": 2600, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "vaiController", "offset": 0, "slot": "21", - "type": "t_contract(VAIControllerInterface)15582" + "type": "t_contract(VAIControllerInterface)15644" }, { - "astId": 2503, + "astId": 2604, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "mintedVAIs", "offset": 0, @@ -2313,7 +2313,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2505, + "astId": 2606, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "vaiMintRate", "offset": 0, @@ -2321,7 +2321,7 @@ "type": "t_uint256" }, { - "astId": 2507, + "astId": 2608, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "mintVAIGuardianPaused", "offset": 0, @@ -2329,7 +2329,7 @@ "type": "t_bool" }, { - "astId": 2509, + "astId": 2610, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "repayVAIGuardianPaused", "offset": 1, @@ -2337,7 +2337,7 @@ "type": "t_bool" }, { - "astId": 2511, + "astId": 2612, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "protocolPaused", "offset": 2, @@ -2345,7 +2345,7 @@ "type": "t_bool" }, { - "astId": 2513, + "astId": 2614, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusVAIRate", "offset": 0, @@ -2353,7 +2353,7 @@ "type": "t_uint256" }, { - "astId": 2518, + "astId": 2619, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusVAIVaultRate", "offset": 0, @@ -2361,7 +2361,7 @@ "type": "t_uint256" }, { - "astId": 2520, + "astId": 2621, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "vaiVaultAddress", "offset": 0, @@ -2369,7 +2369,7 @@ "type": "t_address" }, { - "astId": 2522, + "astId": 2623, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "releaseStartBlock", "offset": 0, @@ -2377,7 +2377,7 @@ "type": "t_uint256" }, { - "astId": 2524, + "astId": 2625, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "minReleaseAmount", "offset": 0, @@ -2385,7 +2385,7 @@ "type": "t_uint256" }, { - "astId": 2529, + "astId": 2630, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "borrowCapGuardian", "offset": 0, @@ -2393,7 +2393,7 @@ "type": "t_address" }, { - "astId": 2533, + "astId": 2634, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "borrowCaps", "offset": 0, @@ -2401,7 +2401,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2538, + "astId": 2639, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "treasuryGuardian", "offset": 0, @@ -2409,7 +2409,7 @@ "type": "t_address" }, { - "astId": 2540, + "astId": 2641, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "treasuryAddress", "offset": 0, @@ -2417,7 +2417,7 @@ "type": "t_address" }, { - "astId": 2542, + "astId": 2643, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "treasuryPercent", "offset": 0, @@ -2425,7 +2425,7 @@ "type": "t_uint256" }, { - "astId": 2549, + "astId": 2650, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusContributorSpeeds", "offset": 0, @@ -2433,7 +2433,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2553, + "astId": 2654, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "lastContributorBlock", "offset": 0, @@ -2441,7 +2441,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2558, + "astId": 2659, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "liquidatorContract", "offset": 0, @@ -2449,15 +2449,15 @@ "type": "t_address" }, { - "astId": 2563, + "astId": 2664, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "comptrollerLens", "offset": 0, "slot": "38", - "type": "t_contract(ComptrollerLensInterface)2377" + "type": "t_contract(ComptrollerLensInterface)2478" }, { - "astId": 2570, + "astId": 2671, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "supplyCaps", "offset": 0, @@ -2465,7 +2465,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2575, + "astId": 2676, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "accessControl", "offset": 0, @@ -2473,7 +2473,7 @@ "type": "t_address" }, { - "astId": 2581, + "astId": 2682, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_actionPaused", "offset": 0, @@ -2481,7 +2481,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" }, { - "astId": 2588, + "astId": 2689, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusBorrowSpeeds", "offset": 0, @@ -2489,7 +2489,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2592, + "astId": 2693, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusSupplySpeeds", "offset": 0, @@ -2497,7 +2497,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2601, + "astId": 2702, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "approvedDelegates", "offset": 0, @@ -2505,7 +2505,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2608, + "astId": 2709, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "isForcedLiquidationEnabled", "offset": 0, @@ -2513,23 +2513,23 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2626, + "astId": 2727, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_selectorToFacetAndPosition", "offset": 0, "slot": "46", - "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2616_storage)" + "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2717_storage)" }, { - "astId": 2630, + "astId": 2731, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_facetFunctionSelectors", "offset": 0, "slot": "47", - "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2622_storage)" + "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2723_storage)" }, { - "astId": 2633, + "astId": 2734, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_facetAddresses", "offset": 0, @@ -2537,15 +2537,15 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 2638, + "astId": 2739, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "prime", "offset": 0, "slot": "49", - "type": "t_contract(IPrime)12283" + "type": "t_contract(IPrime)12523" }, { - "astId": 2647, + "astId": 2748, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "isForcedLiquidationEnabledForUser", "offset": 0, @@ -2553,7 +2553,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2652, + "astId": 2753, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "xvs", "offset": 0, @@ -2561,7 +2561,7 @@ "type": "t_address" }, { - "astId": 2654, + "astId": 2755, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "xvsVToken", "offset": 0, @@ -2587,8 +2587,8 @@ "label": "bytes4[]", "numberOfBytes": "32" }, - "t_array(t_contract(VToken)23033)dyn_storage": { - "base": "t_contract(VToken)23033", + "t_array(t_contract(VToken)23484)dyn_storage": { + "base": "t_contract(VToken)23484", "encoding": "dynamic_array", "label": "contract VToken[]", "numberOfBytes": "32" @@ -2603,37 +2603,37 @@ "label": "bytes4", "numberOfBytes": "4" }, - "t_contract(ComptrollerLensInterface)2377": { + "t_contract(ComptrollerLensInterface)2478": { "encoding": "inplace", "label": "contract ComptrollerLensInterface", "numberOfBytes": "20" }, - "t_contract(IPrime)12283": { + "t_contract(IPrime)12523": { "encoding": "inplace", "label": "contract IPrime", "numberOfBytes": "20" }, - "t_contract(PriceOracle)12106": { + "t_contract(PriceOracle)12346": { "encoding": "inplace", "label": "contract PriceOracle", "numberOfBytes": "20" }, - "t_contract(VAIControllerInterface)15582": { + "t_contract(VAIControllerInterface)15644": { "encoding": "inplace", "label": "contract VAIControllerInterface", "numberOfBytes": "20" }, - "t_contract(VToken)23033": { + "t_contract(VToken)23484": { "encoding": "inplace", "label": "contract VToken", "numberOfBytes": "20" }, - "t_mapping(t_address,t_array(t_contract(VToken)23033)dyn_storage)": { + "t_mapping(t_address,t_array(t_contract(VToken)23484)dyn_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => contract VToken[])", "numberOfBytes": "32", - "value": "t_array(t_contract(VToken)23033)dyn_storage" + "value": "t_array(t_contract(VToken)23484)dyn_storage" }, "t_mapping(t_address,t_bool)": { "encoding": "mapping", @@ -2663,26 +2663,26 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_bool)" }, - "t_mapping(t_address,t_struct(FacetFunctionSelectors)2622_storage)": { + "t_mapping(t_address,t_struct(FacetFunctionSelectors)2723_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV13Storage.FacetFunctionSelectors)", "numberOfBytes": "32", - "value": "t_struct(FacetFunctionSelectors)2622_storage" + "value": "t_struct(FacetFunctionSelectors)2723_storage" }, - "t_mapping(t_address,t_struct(Market)2437_storage)": { + "t_mapping(t_address,t_struct(Market)2538_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.Market)", "numberOfBytes": "32", - "value": "t_struct(Market)2437_storage" + "value": "t_struct(Market)2538_storage" }, - "t_mapping(t_address,t_struct(VenusMarketState)2464_storage)": { + "t_mapping(t_address,t_struct(VenusMarketState)2565_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.VenusMarketState)", "numberOfBytes": "32", - "value": "t_struct(VenusMarketState)2464_storage" + "value": "t_struct(VenusMarketState)2565_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -2691,12 +2691,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2616_storage)": { + "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2717_storage)": { "encoding": "mapping", "key": "t_bytes4", "label": "mapping(bytes4 => struct ComptrollerV13Storage.FacetAddressAndPosition)", "numberOfBytes": "32", - "value": "t_struct(FacetAddressAndPosition)2616_storage" + "value": "t_struct(FacetAddressAndPosition)2717_storage" }, "t_mapping(t_uint256,t_bool)": { "encoding": "mapping", @@ -2705,12 +2705,12 @@ "numberOfBytes": "32", "value": "t_bool" }, - "t_struct(FacetAddressAndPosition)2616_storage": { + "t_struct(FacetAddressAndPosition)2717_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetAddressAndPosition", "members": [ { - "astId": 2613, + "astId": 2714, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "facetAddress", "offset": 0, @@ -2718,7 +2718,7 @@ "type": "t_address" }, { - "astId": 2615, + "astId": 2716, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "functionSelectorPosition", "offset": 20, @@ -2728,12 +2728,12 @@ ], "numberOfBytes": "32" }, - "t_struct(FacetFunctionSelectors)2622_storage": { + "t_struct(FacetFunctionSelectors)2723_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetFunctionSelectors", "members": [ { - "astId": 2619, + "astId": 2720, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "functionSelectors", "offset": 0, @@ -2741,7 +2741,7 @@ "type": "t_array(t_bytes4)dyn_storage" }, { - "astId": 2621, + "astId": 2722, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "facetAddressPosition", "offset": 0, @@ -2751,12 +2751,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Market)2437_storage": { + "t_struct(Market)2538_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.Market", "members": [ { - "astId": 2428, + "astId": 2529, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "isListed", "offset": 0, @@ -2764,7 +2764,7 @@ "type": "t_bool" }, { - "astId": 2430, + "astId": 2531, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "collateralFactorMantissa", "offset": 0, @@ -2772,7 +2772,7 @@ "type": "t_uint256" }, { - "astId": 2434, + "astId": 2535, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "accountMembership", "offset": 0, @@ -2780,7 +2780,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2436, + "astId": 2537, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "isVenus", "offset": 0, @@ -2790,12 +2790,12 @@ ], "numberOfBytes": "128" }, - "t_struct(VenusMarketState)2464_storage": { + "t_struct(VenusMarketState)2565_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.VenusMarketState", "members": [ { - "astId": 2461, + "astId": 2562, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "index", "offset": 0, @@ -2803,7 +2803,7 @@ "type": "t_uint224" }, { - "astId": 2463, + "astId": 2564, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "block", "offset": 28, diff --git a/deployments/bscmainnet/solcInputs/ce1a4122e5f4f14eccfd5d8b352422cb.json b/deployments/bscmainnet/solcInputs/ce1a4122e5f4f14eccfd5d8b352422cb.json new file mode 100644 index 000000000..d64b98bb3 --- /dev/null +++ b/deployments/bscmainnet/solcInputs/ce1a4122e5f4f14eccfd5d8b352422cb.json @@ -0,0 +1,348 @@ +{ + "language": "Solidity", + "sources": { + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV5.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.5.16;\n\nimport \"./IAccessControlManagerV5.sol\";\n\n/**\n * @title AccessControlledV5\n * @author Venus\n * @notice This contract is helper between access control manager and actual contract. This contract further inherited by other contract (using solidity 0.5.16)\n * to integrate access controlled mechanism. It provides initialise methods and verifying access methods.\n */\ncontract AccessControlledV5 {\n /// @notice Access control manager contract\n IAccessControlManagerV5 private _accessControlManager;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n\n /// @notice Emitted when access control manager contract address is changed\n event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager);\n\n /**\n * @notice Returns the address of the access control manager contract\n */\n function accessControlManager() external view returns (IAccessControlManagerV5) {\n return _accessControlManager;\n }\n\n /**\n * @dev Internal function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n */\n function _setAccessControlManager(address accessControlManager_) internal {\n require(address(accessControlManager_) != address(0), \"invalid acess control manager address\");\n address oldAccessControlManager = address(_accessControlManager);\n _accessControlManager = IAccessControlManagerV5(accessControlManager_);\n emit NewAccessControlManager(oldAccessControlManager, accessControlManager_);\n }\n\n /**\n * @notice Reverts if the call is not allowed by AccessControlManager\n * @param signature Method signature\n */\n function _checkAccessAllowed(string memory signature) internal view {\n bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature);\n\n if (!isAllowedToCall) {\n revert(\"Unauthorized\");\n }\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/GovernorBravoDelegate.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"./GovernorBravoInterfaces.sol\";\n\n/**\n * @title GovernorBravoDelegate\n * @notice Venus Governance latest on chain governance includes several new features including variable proposal routes and fine grained pause control.\n * Variable routes for proposals allows for governance paramaters such as voting threshold and timelocks to be customized based on the risk level and\n * impact of the proposal. Added granularity to the pause control mechanism allows governance to pause individual actions on specific markets,\n * which reduces impact on the protocol as a whole. This is particularly useful when applied to isolated pools.\n *\n * The goal of **Governance** is to increase governance efficiency, while mitigating and eliminating malicious or erroneous proposals.\n *\n * ## Details\n *\n * Governance has **3 main contracts**: **GovernanceBravoDelegate, XVSVault, XVS** token.\n *\n * - XVS token is the protocol token used for protocol users to cast their vote on submitted proposals.\n * - XVSVault is the main staking contract for XVS. Users first stake their XVS in the vault and receive voting power proportional to their staked\n * tokens that they can use to vote on proposals. Users also can choose to delegate their voting power to other users.\n *\n * # Governor Bravo\n *\n * `GovernanceBravoDelegate` is main Venus Governance contract. Users interact with it to:\n * - Submit new proposal\n * - Vote on a proposal\n * - Cancel a proposal\n * - Queue a proposal for execution with a timelock executor contract.\n * `GovernanceBravoDelegate` uses the XVSVault to get restrict certain actions based on a user's voting power. The governance rules it inforces are:\n * - A user's voting power must be greater than the `proposalThreshold` to submit a proposal\n * - If a user's voting power drops below certain amount, anyone can cancel the the proposal. The governance guardian and proposal creator can also\n * cancel a proposal at anytime before it is queued for execution.\n *\n * ## Venus Improvement Proposal\n *\n * Venus Governance allows for Venus Improvement Proposals (VIPs) to be categorized based on their impact and risk levels. This allows for optimizing proposals\n * execution to allow for things such as expediting interest rate changes and quickly updating risk parameters, while moving slower on other types of proposals\n * that can prevent a larger risk to the protocol and are not urgent. There are three different types of VIPs with different proposal paramters:\n *\n * - `NORMAL`\n * - `FASTTRACK`\n * - `CRITICAL`\n *\n * When initializing the `GovernorBravo` contract, the parameters for the three routes are set. The parameters are:\n *\n * - `votingDelay`: The delay in blocks between submitting a proposal and when voting begins\n * - `votingPeriod`: The number of blocks where voting will be open\n * - `proposalThreshold`: The number of votes required in order submit a proposal\n *\n * There is also a separate timelock executor contract for each route, which is used to dispatch the VIP for execution, giving even more control over the\n * flow of each type of VIP.\n *\n * ## Voting\n *\n * After a VIP is proposed, voting is opened after the `votingDelay` has passed. For example, if `votingDelay = 0`, then voting will begin in the next block\n * after the proposal has been submitted. After the delay, the proposal state is `ACTIVE` and users can cast their vote `for`, `against`, or `abstain`,\n * weighted by their total voting power (tokens + delegated voting power). Abstaining from a voting allows for a vote to be cast and optionally include a\n * comment, without the incrementing for or against vote count. The total voting power for the user is obtained by calling XVSVault's `getPriorVotes`.\n *\n * `GovernorBravoDelegate` also accepts [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signatures for voting on proposals via the external function\n * `castVoteBySig`.\n *\n * ## Delegating\n *\n * A users voting power includes the amount of staked XVS the have staked as well as the votes delegate to them. Delegating is the process of a user loaning\n * their voting power to another, so that the latter has the combined voting power of both users. This is an important feature because it allows for a user\n * to let another user who they trust propose or vote in their place.\n *\n * The delegation of votes happens through the `XVSVault` contract by calling the `delegate` or `delegateBySig` functions. These same functions can revert\n * vote delegation by calling the same function with a value of `0`.\n */\ncontract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoEvents {\n /// @notice The name of this contract\n string public constant name = \"Venus Governor Bravo\";\n\n /// @notice The minimum setable proposal threshold\n uint public constant MIN_PROPOSAL_THRESHOLD = 150000e18; // 150,000 Xvs\n\n /// @notice The maximum setable proposal threshold\n uint public constant MAX_PROPOSAL_THRESHOLD = 300000e18; //300,000 Xvs\n\n /// @notice The minimum setable voting period\n uint public constant MIN_VOTING_PERIOD = 20 * 60 * 3; // About 3 hours, 3 secs per block\n\n /// @notice The max setable voting period\n uint public constant MAX_VOTING_PERIOD = 20 * 60 * 24 * 14; // About 2 weeks, 3 secs per block\n\n /// @notice The min setable voting delay\n uint public constant MIN_VOTING_DELAY = 1;\n\n /// @notice The max setable voting delay\n uint public constant MAX_VOTING_DELAY = 20 * 60 * 24 * 7; // About 1 week, 3 secs per block\n\n /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed\n uint public constant quorumVotes = 600000e18; // 600,000 = 2% of Xvs\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the ballot struct used by the contract\n bytes32 public constant BALLOT_TYPEHASH = keccak256(\"Ballot(uint256 proposalId,uint8 support)\");\n\n /**\n * @notice Used to initialize the contract during delegator contructor\n * @param xvsVault_ The address of the XvsVault\n * @param proposalConfigs_ Governance configs for each governance route\n * @param timelocks Timelock addresses for each governance route\n */\n function initialize(\n address xvsVault_,\n ProposalConfig[] memory proposalConfigs_,\n TimelockInterface[] memory timelocks,\n address guardian_\n ) public {\n require(address(proposalTimelocks[0]) == address(0), \"GovernorBravo::initialize: cannot initialize twice\");\n require(msg.sender == admin, \"GovernorBravo::initialize: admin only\");\n require(xvsVault_ != address(0), \"GovernorBravo::initialize: invalid xvs address\");\n require(guardian_ != address(0), \"GovernorBravo::initialize: invalid guardian\");\n require(\n timelocks.length == uint8(ProposalType.CRITICAL) + 1,\n \"GovernorBravo::initialize:number of timelocks should match number of governance routes\"\n );\n require(\n proposalConfigs_.length == uint8(ProposalType.CRITICAL) + 1,\n \"GovernorBravo::initialize:number of proposal configs should match number of governance routes\"\n );\n\n xvsVault = XvsVaultInterface(xvsVault_);\n proposalMaxOperations = 10;\n guardian = guardian_;\n\n //Set parameters for each Governance Route\n uint256 arrLength = proposalConfigs_.length;\n for (uint256 i; i < arrLength; ++i) {\n require(\n proposalConfigs_[i].votingPeriod >= MIN_VOTING_PERIOD,\n \"GovernorBravo::initialize: invalid min voting period\"\n );\n require(\n proposalConfigs_[i].votingPeriod <= MAX_VOTING_PERIOD,\n \"GovernorBravo::initialize: invalid max voting period\"\n );\n require(\n proposalConfigs_[i].votingDelay >= MIN_VOTING_DELAY,\n \"GovernorBravo::initialize: invalid min voting delay\"\n );\n require(\n proposalConfigs_[i].votingDelay <= MAX_VOTING_DELAY,\n \"GovernorBravo::initialize: invalid max voting delay\"\n );\n require(\n proposalConfigs_[i].proposalThreshold >= MIN_PROPOSAL_THRESHOLD,\n \"GovernorBravo::initialize: invalid min proposal threshold\"\n );\n require(\n proposalConfigs_[i].proposalThreshold <= MAX_PROPOSAL_THRESHOLD,\n \"GovernorBravo::initialize: invalid max proposal threshold\"\n );\n require(address(timelocks[i]) != address(0), \"GovernorBravo::initialize:invalid timelock address\");\n\n proposalConfigs[i] = proposalConfigs_[i];\n proposalTimelocks[i] = timelocks[i];\n }\n }\n\n /**\n * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold.\n * targets, values, signatures, and calldatas must be of equal length\n * @dev NOTE: Proposals with duplicate set of actions can not be queued for execution. If the proposals consists\n * of duplicate actions, it's recommended to split those actions into separate proposals\n * @param targets Target addresses for proposal calls\n * @param values BNB values for proposal calls\n * @param signatures Function signatures for proposal calls\n * @param calldatas Calldatas for proposal calls\n * @param description String description of the proposal\n * @param proposalType the type of the proposal (e.g NORMAL, FASTTRACK, CRITICAL)\n * @return Proposal id of new proposal\n */\n function propose(\n address[] memory targets,\n uint[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n string memory description,\n ProposalType proposalType\n ) public returns (uint) {\n // Reject proposals before initiating as Governor\n require(initialProposalId != 0, \"GovernorBravo::propose: Governor Bravo not active\");\n require(\n xvsVault.getPriorVotes(msg.sender, sub256(block.number, 1)) >=\n proposalConfigs[uint8(proposalType)].proposalThreshold,\n \"GovernorBravo::propose: proposer votes below proposal threshold\"\n );\n require(\n targets.length == values.length &&\n targets.length == signatures.length &&\n targets.length == calldatas.length,\n \"GovernorBravo::propose: proposal function information arity mismatch\"\n );\n require(targets.length != 0, \"GovernorBravo::propose: must provide actions\");\n require(targets.length <= proposalMaxOperations, \"GovernorBravo::propose: too many actions\");\n\n uint latestProposalId = latestProposalIds[msg.sender];\n if (latestProposalId != 0) {\n ProposalState proposersLatestProposalState = state(latestProposalId);\n require(\n proposersLatestProposalState != ProposalState.Active,\n \"GovernorBravo::propose: one live proposal per proposer, found an already active proposal\"\n );\n require(\n proposersLatestProposalState != ProposalState.Pending,\n \"GovernorBravo::propose: one live proposal per proposer, found an already pending proposal\"\n );\n }\n\n uint startBlock = add256(block.number, proposalConfigs[uint8(proposalType)].votingDelay);\n uint endBlock = add256(startBlock, proposalConfigs[uint8(proposalType)].votingPeriod);\n\n proposalCount++;\n Proposal memory newProposal = Proposal({\n id: proposalCount,\n proposer: msg.sender,\n eta: 0,\n targets: targets,\n values: values,\n signatures: signatures,\n calldatas: calldatas,\n startBlock: startBlock,\n endBlock: endBlock,\n forVotes: 0,\n againstVotes: 0,\n abstainVotes: 0,\n canceled: false,\n executed: false,\n proposalType: uint8(proposalType)\n });\n\n proposals[newProposal.id] = newProposal;\n latestProposalIds[newProposal.proposer] = newProposal.id;\n\n emit ProposalCreated(\n newProposal.id,\n msg.sender,\n targets,\n values,\n signatures,\n calldatas,\n startBlock,\n endBlock,\n description,\n uint8(proposalType)\n );\n return newProposal.id;\n }\n\n /**\n * @notice Queues a proposal of state succeeded\n * @param proposalId The id of the proposal to queue\n */\n function queue(uint proposalId) external {\n require(\n state(proposalId) == ProposalState.Succeeded,\n \"GovernorBravo::queue: proposal can only be queued if it is succeeded\"\n );\n Proposal storage proposal = proposals[proposalId];\n uint eta = add256(block.timestamp, proposalTimelocks[uint8(proposal.proposalType)].delay());\n for (uint i; i < proposal.targets.length; ++i) {\n queueOrRevertInternal(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n eta,\n uint8(proposal.proposalType)\n );\n }\n proposal.eta = eta;\n emit ProposalQueued(proposalId, eta);\n }\n\n function queueOrRevertInternal(\n address target,\n uint value,\n string memory signature,\n bytes memory data,\n uint eta,\n uint8 proposalType\n ) internal {\n require(\n !proposalTimelocks[proposalType].queuedTransactions(\n keccak256(abi.encode(target, value, signature, data, eta))\n ),\n \"GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta\"\n );\n proposalTimelocks[proposalType].queueTransaction(target, value, signature, data, eta);\n }\n\n /**\n * @notice Executes a queued proposal if eta has passed\n * @param proposalId The id of the proposal to execute\n */\n function execute(uint proposalId) external {\n require(\n state(proposalId) == ProposalState.Queued,\n \"GovernorBravo::execute: proposal can only be executed if it is queued\"\n );\n Proposal storage proposal = proposals[proposalId];\n proposal.executed = true;\n for (uint i; i < proposal.targets.length; ++i) {\n proposalTimelocks[uint8(proposal.proposalType)].executeTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n proposal.eta\n );\n }\n emit ProposalExecuted(proposalId);\n }\n\n /**\n * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold\n * @param proposalId The id of the proposal to cancel\n */\n function cancel(uint proposalId) external {\n require(state(proposalId) != ProposalState.Executed, \"GovernorBravo::cancel: cannot cancel executed proposal\");\n\n Proposal storage proposal = proposals[proposalId];\n require(\n msg.sender == guardian ||\n msg.sender == proposal.proposer ||\n xvsVault.getPriorVotes(proposal.proposer, sub256(block.number, 1)) <\n proposalConfigs[proposal.proposalType].proposalThreshold,\n \"GovernorBravo::cancel: proposer above threshold\"\n );\n\n proposal.canceled = true;\n for (uint i = 0; i < proposal.targets.length; i++) {\n proposalTimelocks[proposal.proposalType].cancelTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n proposal.eta\n );\n }\n\n emit ProposalCanceled(proposalId);\n }\n\n /**\n * @notice Gets actions of a proposal\n * @param proposalId the id of the proposal\n * @return targets, values, signatures, and calldatas of the proposal actions\n */\n function getActions(\n uint proposalId\n )\n external\n view\n returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas)\n {\n Proposal storage p = proposals[proposalId];\n return (p.targets, p.values, p.signatures, p.calldatas);\n }\n\n /**\n * @notice Gets the receipt for a voter on a given proposal\n * @param proposalId the id of proposal\n * @param voter The address of the voter\n * @return The voting receipt\n */\n function getReceipt(uint proposalId, address voter) external view returns (Receipt memory) {\n return proposals[proposalId].receipts[voter];\n }\n\n /**\n * @notice Gets the state of a proposal\n * @param proposalId The id of the proposal\n * @return Proposal state\n */\n function state(uint proposalId) public view returns (ProposalState) {\n require(\n proposalCount >= proposalId && proposalId > initialProposalId,\n \"GovernorBravo::state: invalid proposal id\"\n );\n Proposal storage proposal = proposals[proposalId];\n if (proposal.canceled) {\n return ProposalState.Canceled;\n } else if (block.number <= proposal.startBlock) {\n return ProposalState.Pending;\n } else if (block.number <= proposal.endBlock) {\n return ProposalState.Active;\n } else if (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < quorumVotes) {\n return ProposalState.Defeated;\n } else if (proposal.eta == 0) {\n return ProposalState.Succeeded;\n } else if (proposal.executed) {\n return ProposalState.Executed;\n } else if (\n block.timestamp >= add256(proposal.eta, proposalTimelocks[uint8(proposal.proposalType)].GRACE_PERIOD())\n ) {\n return ProposalState.Expired;\n } else {\n return ProposalState.Queued;\n }\n }\n\n /**\n * @notice Cast a vote for a proposal\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n */\n function castVote(uint proposalId, uint8 support) external {\n emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), \"\");\n }\n\n /**\n * @notice Cast a vote for a proposal with a reason\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @param reason The reason given for the vote by the voter\n */\n function castVoteWithReason(uint proposalId, uint8 support, string calldata reason) external {\n emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), reason);\n }\n\n /**\n * @notice Cast a vote for a proposal by signature\n * @dev External function that accepts EIP-712 signatures for voting on proposals.\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @param v recovery id of ECDSA signature\n * @param r part of the ECDSA sig output\n * @param s part of the ECDSA sig output\n */\n function castVoteBySig(uint proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"GovernorBravo::castVoteBySig: invalid signature\");\n emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), \"\");\n }\n\n /**\n * @notice Internal function that caries out voting logic\n * @param voter The voter that is casting their vote\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @return The number of votes cast\n */\n function castVoteInternal(address voter, uint proposalId, uint8 support) internal returns (uint96) {\n require(state(proposalId) == ProposalState.Active, \"GovernorBravo::castVoteInternal: voting is closed\");\n require(support <= 2, \"GovernorBravo::castVoteInternal: invalid vote type\");\n Proposal storage proposal = proposals[proposalId];\n Receipt storage receipt = proposal.receipts[voter];\n require(receipt.hasVoted == false, \"GovernorBravo::castVoteInternal: voter already voted\");\n uint96 votes = xvsVault.getPriorVotes(voter, proposal.startBlock);\n\n if (support == 0) {\n proposal.againstVotes = add256(proposal.againstVotes, votes);\n } else if (support == 1) {\n proposal.forVotes = add256(proposal.forVotes, votes);\n } else if (support == 2) {\n proposal.abstainVotes = add256(proposal.abstainVotes, votes);\n }\n\n receipt.hasVoted = true;\n receipt.support = support;\n receipt.votes = votes;\n\n return votes;\n }\n\n /**\n * @notice Sets the new governance guardian\n * @param newGuardian the address of the new guardian\n */\n function _setGuardian(address newGuardian) external {\n require(msg.sender == guardian || msg.sender == admin, \"GovernorBravo::_setGuardian: admin or guardian only\");\n require(newGuardian != address(0), \"GovernorBravo::_setGuardian: cannot live without a guardian\");\n address oldGuardian = guardian;\n guardian = newGuardian;\n\n emit NewGuardian(oldGuardian, newGuardian);\n }\n\n /**\n * @notice Initiate the GovernorBravo contract\n * @dev Admin only. Sets initial proposal id which initiates the contract, ensuring a continuous proposal id count\n * @param governorAlpha The address for the Governor to continue the proposal id count from\n */\n function _initiate(address governorAlpha) external {\n require(msg.sender == admin, \"GovernorBravo::_initiate: admin only\");\n require(initialProposalId == 0, \"GovernorBravo::_initiate: can only initiate once\");\n proposalCount = GovernorAlphaInterface(governorAlpha).proposalCount();\n initialProposalId = proposalCount;\n for (uint256 i; i < uint8(ProposalType.CRITICAL) + 1; ++i) {\n proposalTimelocks[i].acceptAdmin();\n }\n }\n\n /**\n * @notice Set max proposal operations\n * @dev Admin only.\n * @param proposalMaxOperations_ Max proposal operations\n */\n function _setProposalMaxOperations(uint proposalMaxOperations_) external {\n require(msg.sender == admin, \"GovernorBravo::_setProposalMaxOperations: admin only\");\n uint oldProposalMaxOperations = proposalMaxOperations;\n proposalMaxOperations = proposalMaxOperations_;\n\n emit ProposalMaxOperationsUpdated(oldProposalMaxOperations, proposalMaxOperations_);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n */\n function _setPendingAdmin(address newPendingAdmin) external {\n // Check caller = admin\n require(msg.sender == admin, \"GovernorBravo:_setPendingAdmin: admin only\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n */\n function _acceptAdmin() external {\n // Check caller is pendingAdmin and pendingAdmin ≠ address(0)\n require(\n msg.sender == pendingAdmin && msg.sender != address(0),\n \"GovernorBravo:_acceptAdmin: pending admin only\"\n );\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n function add256(uint256 a, uint256 b) internal pure returns (uint) {\n uint c = a + b;\n require(c >= a, \"addition overflow\");\n return c;\n }\n\n function sub256(uint256 a, uint256 b) internal pure returns (uint) {\n require(b <= a, \"subtraction underflow\");\n return a - b;\n }\n\n function getChainIdInternal() internal pure returns (uint) {\n uint chainId;\n assembly {\n chainId := chainid()\n }\n return chainId;\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/GovernorBravoInterfaces.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\n/**\n * @title GovernorBravoEvents\n * @author Venus\n * @notice Set of events emitted by the GovernorBravo contracts.\n */\ncontract GovernorBravoEvents {\n /// @notice An event emitted when a new proposal is created\n event ProposalCreated(\n uint id,\n address proposer,\n address[] targets,\n uint[] values,\n string[] signatures,\n bytes[] calldatas,\n uint startBlock,\n uint endBlock,\n string description,\n uint8 proposalType\n );\n\n /// @notice An event emitted when a vote has been cast on a proposal\n /// @param voter The address which casted a vote\n /// @param proposalId The proposal id which was voted on\n /// @param support Support value for the vote. 0=against, 1=for, 2=abstain\n /// @param votes Number of votes which were cast by the voter\n /// @param reason The reason given for the vote by the voter\n event VoteCast(address indexed voter, uint proposalId, uint8 support, uint votes, string reason);\n\n /// @notice An event emitted when a proposal has been canceled\n event ProposalCanceled(uint id);\n\n /// @notice An event emitted when a proposal has been queued in the Timelock\n event ProposalQueued(uint id, uint eta);\n\n /// @notice An event emitted when a proposal has been executed in the Timelock\n event ProposalExecuted(uint id);\n\n /// @notice An event emitted when the voting delay is set\n event VotingDelaySet(uint oldVotingDelay, uint newVotingDelay);\n\n /// @notice An event emitted when the voting period is set\n event VotingPeriodSet(uint oldVotingPeriod, uint newVotingPeriod);\n\n /// @notice Emitted when implementation is changed\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /// @notice Emitted when proposal threshold is set\n event ProposalThresholdSet(uint oldProposalThreshold, uint newProposalThreshold);\n\n /// @notice Emitted when pendingAdmin is changed\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /// @notice Emitted when pendingAdmin is accepted, which means admin is updated\n event NewAdmin(address oldAdmin, address newAdmin);\n\n /// @notice Emitted when the new guardian address is set\n event NewGuardian(address oldGuardian, address newGuardian);\n\n /// @notice Emitted when the maximum number of operations in one proposal is updated\n event ProposalMaxOperationsUpdated(uint oldMaxOperations, uint newMaxOperations);\n}\n\n/**\n * @title GovernorBravoDelegatorStorage\n * @author Venus\n * @notice Storage layout of the `GovernorBravoDelegator` contract\n */\ncontract GovernorBravoDelegatorStorage {\n /// @notice Administrator for this contract\n address public admin;\n\n /// @notice Pending administrator for this contract\n address public pendingAdmin;\n\n /// @notice Active brains of Governor\n address public implementation;\n}\n\n/**\n * @title GovernorBravoDelegateStorageV1\n * @dev For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new\n * contract which implements GovernorBravoDelegateStorageV1 and following the naming convention\n * GovernorBravoDelegateStorageVX.\n */\ncontract GovernorBravoDelegateStorageV1 is GovernorBravoDelegatorStorage {\n /// @notice DEPRECATED The delay before voting on a proposal may take place, once proposed, in blocks\n uint public votingDelay;\n\n /// @notice DEPRECATED The duration of voting on a proposal, in blocks\n uint public votingPeriod;\n\n /// @notice DEPRECATED The number of votes required in order for a voter to become a proposer\n uint public proposalThreshold;\n\n /// @notice Initial proposal id set at become\n uint public initialProposalId;\n\n /// @notice The total number of proposals\n uint public proposalCount;\n\n /// @notice The address of the Venus Protocol Timelock\n TimelockInterface public timelock;\n\n /// @notice The address of the Venus governance token\n XvsVaultInterface public xvsVault;\n\n /// @notice The official record of all proposals ever proposed\n mapping(uint => Proposal) public proposals;\n\n /// @notice The latest proposal for each proposer\n mapping(address => uint) public latestProposalIds;\n\n struct Proposal {\n /// @notice Unique id for looking up a proposal\n uint id;\n /// @notice Creator of the proposal\n address proposer;\n /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds\n uint eta;\n /// @notice the ordered list of target addresses for calls to be made\n address[] targets;\n /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made\n uint[] values;\n /// @notice The ordered list of function signatures to be called\n string[] signatures;\n /// @notice The ordered list of calldata to be passed to each call\n bytes[] calldatas;\n /// @notice The block at which voting begins: holders must delegate their votes prior to this block\n uint startBlock;\n /// @notice The block at which voting ends: votes must be cast prior to this block\n uint endBlock;\n /// @notice Current number of votes in favor of this proposal\n uint forVotes;\n /// @notice Current number of votes in opposition to this proposal\n uint againstVotes;\n /// @notice Current number of votes for abstaining for this proposal\n uint abstainVotes;\n /// @notice Flag marking whether the proposal has been canceled\n bool canceled;\n /// @notice Flag marking whether the proposal has been executed\n bool executed;\n /// @notice Receipts of ballots for the entire set of voters\n mapping(address => Receipt) receipts;\n /// @notice The type of the proposal\n uint8 proposalType;\n }\n\n /// @notice Ballot receipt record for a voter\n struct Receipt {\n /// @notice Whether or not a vote has been cast\n bool hasVoted;\n /// @notice Whether or not the voter supports the proposal or abstains\n uint8 support;\n /// @notice The number of votes the voter had, which were cast\n uint96 votes;\n }\n\n /// @notice Possible states that a proposal may be in\n enum ProposalState {\n Pending,\n Active,\n Canceled,\n Defeated,\n Succeeded,\n Queued,\n Expired,\n Executed\n }\n\n /// @notice The maximum number of actions that can be included in a proposal\n uint public proposalMaxOperations;\n\n /// @notice A privileged role that can cancel any proposal\n address public guardian;\n}\n\n/**\n * @title GovernorBravoDelegateStorageV2\n * @dev For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new\n * contract which implements GovernorBravoDelegateStorageV2 and following the naming convention\n * GovernorBravoDelegateStorageVX.\n */\ncontract GovernorBravoDelegateStorageV2 is GovernorBravoDelegateStorageV1 {\n enum ProposalType {\n NORMAL,\n FASTTRACK,\n CRITICAL\n }\n\n struct ProposalConfig {\n /// @notice The delay before voting on a proposal may take place, once proposed, in blocks\n uint256 votingDelay;\n /// @notice The duration of voting on a proposal, in blocks\n uint256 votingPeriod;\n /// @notice The number of votes required in order for a voter to become a proposer\n uint256 proposalThreshold;\n }\n\n /// @notice mapping containing configuration for each proposal type\n mapping(uint => ProposalConfig) public proposalConfigs;\n\n /// @notice mapping containing Timelock addresses for each proposal type\n mapping(uint => TimelockInterface) public proposalTimelocks;\n}\n\n/**\n * @title TimelockInterface\n * @author Venus\n * @notice Interface implemented by the Timelock contract.\n */\ninterface TimelockInterface {\n function delay() external view returns (uint);\n\n function GRACE_PERIOD() external view returns (uint);\n\n function acceptAdmin() external;\n\n function queuedTransactions(bytes32 hash) external view returns (bool);\n\n function queueTransaction(\n address target,\n uint value,\n string calldata signature,\n bytes calldata data,\n uint eta\n ) external returns (bytes32);\n\n function cancelTransaction(\n address target,\n uint value,\n string calldata signature,\n bytes calldata data,\n uint eta\n ) external;\n\n function executeTransaction(\n address target,\n uint value,\n string calldata signature,\n bytes calldata data,\n uint eta\n ) external payable returns (bytes memory);\n}\n\ninterface XvsVaultInterface {\n function getPriorVotes(address account, uint blockNumber) external view returns (uint96);\n}\n\ninterface GovernorAlphaInterface {\n /// @notice The total number of proposals\n function proposalCount() external returns (uint);\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.5.16;\n\n/**\n * @title IAccessControlManagerV5\n * @author Venus\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\n */\ninterface IAccessControlManagerV5 {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n\n /**\n * @notice Gives a function call permission to one single account\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n * \t\tMay emit a {RoleGranted} event.\n * @param contractAddress address of contract for which call permissions will be granted\n * @param functionSig signature e.g. \"functionName(uint,bool)\"\n */\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\n\n /**\n * @notice Revokes an account's permission to a particular function call\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n * \t\tMay emit a {RoleRevoked} event.\n * @param contractAddress address of contract for which call permissions will be revoked\n * @param functionSig signature e.g. \"functionName(uint,bool)\"\n */\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) external;\n\n /**\n * @notice Verifies if the given account can call a praticular contract's function\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\n * @param account address (eoa or contract) for which call permissions will be checked\n * @param functionSig signature e.g. \"functionName(uint,bool)\"\n * @return false if the user account cannot call the particular contract function\n *\n */\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\n\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) external view returns (bool);\n}\n" + }, + "@venusprotocol/solidity-utilities/contracts/TimeManagerV5.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.5.16;\n\ncontract TimeManagerV5 {\n /// @dev The approximate number of seconds per year\n uint256 public constant SECONDS_PER_YEAR = 31_536_000;\n\n /// @notice Number of blocks per year or seconds per year\n uint256 public blocksOrSecondsPerYear;\n\n /// @dev Sets true when block timestamp is used\n bool public isTimeBased;\n\n /// @dev Sets true when contract is initialized\n bool private isInitialized;\n\n /// @notice Deprecated slot for _getCurrentSlot function pointer\n bytes8 private __deprecatedSlot1;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n\n /**\n * @dev Function to simply retrieve block number or block timestamp\n * @return Current block number or block timestamp\n */\n function getBlockNumberOrTimestamp() public view returns (uint256) {\n return isTimeBased ? _getBlockTimestamp() : _getBlockNumber();\n }\n\n /**\n * @dev Initializes the contract to use either blocks or seconds\n * @param timeBased_ A boolean indicating whether the contract is based on time or block\n * If timeBased is true than blocksPerYear_ param is ignored as blocksOrSecondsPerYear is set to SECONDS_PER_YEAR\n * @param blocksPerYear_ The number of blocks per year\n */\n function _initializeTimeManager(bool timeBased_, uint256 blocksPerYear_) internal {\n if (isInitialized) revert(\"Already initialized TimeManager\");\n\n if (!timeBased_ && blocksPerYear_ == 0) {\n revert(\"Invalid blocks per year\");\n }\n if (timeBased_ && blocksPerYear_ != 0) {\n revert(\"Invalid time based configuration\");\n }\n\n isTimeBased = timeBased_;\n blocksOrSecondsPerYear = timeBased_ ? SECONDS_PER_YEAR : blocksPerYear_;\n isInitialized = true;\n }\n\n /**\n * @dev Returns the current timestamp in seconds\n * @return The current timestamp\n */\n function _getBlockTimestamp() private view returns (uint256) {\n return block.timestamp;\n }\n\n /**\n * @dev Returns the current block number\n * @return The current block number\n */\n function _getBlockNumber() private view returns (uint256) {\n return block.number;\n }\n}\n" + }, + "contracts/Comptroller/ComptrollerInterface.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VToken.sol\";\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Tokens/VAI/VAIControllerInterface.sol\";\nimport { ComptrollerTypes } from \"./ComptrollerStorage.sol\";\n\ncontract ComptrollerInterface {\n /// @notice Indicator that this is a Comptroller contract (for inspection)\n bool public constant isComptroller = true;\n\n /*** Assets You Are In ***/\n\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\n\n function exitMarket(address vToken) external returns (uint);\n\n /*** Policy Hooks ***/\n\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\n\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\n\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\n\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\n\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\n\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\n\n function repayBorrowAllowed(\n address vToken,\n address payer,\n address borrower,\n uint repayAmount\n ) external returns (uint);\n\n function repayBorrowVerify(\n address vToken,\n address payer,\n address borrower,\n uint repayAmount,\n uint borrowerIndex\n ) external;\n\n function liquidateBorrowAllowed(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint repayAmount\n ) external returns (uint);\n\n function liquidateBorrowVerify(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint repayAmount,\n uint seizeTokens\n ) external;\n\n function seizeAllowed(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint seizeTokens\n ) external returns (uint);\n\n function seizeVerify(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint seizeTokens\n ) external;\n\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\n\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\n\n /*** Liquidity/Liquidation Calculations ***/\n\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint repayAmount\n ) external view returns (uint, uint);\n\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\n\n function liquidateVAICalculateSeizeTokens(\n address vTokenCollateral,\n uint repayAmount\n ) external view returns (uint, uint);\n\n function getXVSAddress() public view returns (address);\n\n function markets(address) external view returns (bool, uint);\n\n function oracle() external view returns (PriceOracle);\n\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\n\n function getAssetsIn(address) external view returns (VToken[] memory);\n\n function claimVenus(address) external;\n\n function venusAccrued(address) external view returns (uint);\n\n function venusSupplySpeeds(address) external view returns (uint);\n\n function venusBorrowSpeeds(address) external view returns (uint);\n\n function getAllMarkets() external view returns (VToken[] memory);\n\n function venusSupplierIndex(address, address) external view returns (uint);\n\n function venusInitialIndex() external view returns (uint224);\n\n function venusBorrowerIndex(address, address) external view returns (uint);\n\n function venusBorrowState(address) external view returns (uint224, uint32);\n\n function venusSupplyState(address) external view returns (uint224, uint32);\n\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\n\n function vaiController() external view returns (VAIControllerInterface);\n\n function liquidationIncentiveMantissa() external view returns (uint);\n\n function protocolPaused() external view returns (bool);\n\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\n\n function mintedVAIs(address user) external view returns (uint);\n\n function vaiMintRate() external view returns (uint);\n}\n\ninterface IVAIVault {\n function updatePendingRewards() external;\n}\n\ninterface IComptroller {\n function liquidationIncentiveMantissa() external view returns (uint);\n\n /*** Treasury Data ***/\n function treasuryAddress() external view returns (address);\n\n function treasuryPercent() external view returns (uint);\n}\n" + }, + "contracts/Comptroller/ComptrollerLensInterface.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Tokens/VTokens/VToken.sol\";\n\ninterface ComptrollerLensInterface {\n function liquidateCalculateSeizeTokens(\n address comptroller,\n address vTokenBorrowed,\n address vTokenCollateral,\n uint actualRepayAmount\n ) external view returns (uint, uint);\n\n function liquidateVAICalculateSeizeTokens(\n address comptroller,\n address vTokenCollateral,\n uint actualRepayAmount\n ) external view returns (uint, uint);\n\n function getHypotheticalAccountLiquidity(\n address comptroller,\n address account,\n VToken vTokenModify,\n uint redeemTokens,\n uint borrowAmount\n ) external view returns (uint, uint, uint);\n}\n" + }, + "contracts/Comptroller/ComptrollerStorage.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity ^0.5.16;\n\nimport { VToken } from \"../Tokens/VTokens/VToken.sol\";\nimport { PriceOracle } from \"../Oracle/PriceOracle.sol\";\nimport { VAIControllerInterface } from \"../Tokens/VAI/VAIControllerInterface.sol\";\nimport { ComptrollerLensInterface } from \"./ComptrollerLensInterface.sol\";\nimport { IPrime } from \"../Tokens/Prime/IPrime.sol\";\n\ninterface ComptrollerTypes {\n enum Action {\n MINT,\n REDEEM,\n BORROW,\n REPAY,\n SEIZE,\n LIQUIDATE,\n TRANSFER,\n ENTER_MARKET,\n EXIT_MARKET\n }\n}\n\ncontract UnitrollerAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of Unitroller\n */\n address public comptrollerImplementation;\n\n /**\n * @notice Pending brains of Unitroller\n */\n address public pendingComptrollerImplementation;\n}\n\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\n /**\n * @notice Oracle which gives the price of any given asset\n */\n PriceOracle public oracle;\n\n /**\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\n */\n uint256 public closeFactorMantissa;\n\n /**\n * @notice Multiplier representing the discount on collateral that a liquidator receives\n */\n uint256 public liquidationIncentiveMantissa;\n\n /**\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\n */\n uint256 public maxAssets;\n\n /**\n * @notice Per-account mapping of \"assets you are in\", capped by maxAssets\n */\n mapping(address => VToken[]) public accountAssets;\n\n struct Market {\n /// @notice Whether or not this market is listed\n bool isListed;\n /**\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\n * For instance, 0.9 to allow borrowing 90% of collateral value.\n * Must be between 0 and 1, and stored as a mantissa.\n */\n uint256 collateralFactorMantissa;\n /// @notice Per-market mapping of \"accounts in this asset\"\n mapping(address => bool) accountMembership;\n /// @notice Whether or not this market receives XVS\n bool isVenus;\n }\n\n /**\n * @notice Official mapping of vTokens -> Market metadata\n * @dev Used e.g. to determine if a market is supported\n */\n mapping(address => Market) public markets;\n\n /**\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\n */\n address public pauseGuardian;\n\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\n bool private _mintGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n bool private _borrowGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n bool internal transferGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n bool internal seizeGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n mapping(address => bool) internal mintGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n mapping(address => bool) internal borrowGuardianPaused;\n\n struct VenusMarketState {\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\n uint224 index;\n /// @notice The block number the index was last updated at\n uint32 block;\n }\n\n /// @notice A list of all markets\n VToken[] public allMarkets;\n\n /// @notice The rate at which the flywheel distributes XVS, per block\n uint256 internal venusRate;\n\n /// @notice The portion of venusRate that each market currently receives\n mapping(address => uint256) internal venusSpeeds;\n\n /// @notice The Venus market supply state for each market\n mapping(address => VenusMarketState) public venusSupplyState;\n\n /// @notice The Venus market borrow state for each market\n mapping(address => VenusMarketState) public venusBorrowState;\n\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\n\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\n\n /// @notice The XVS accrued but not yet transferred to each user\n mapping(address => uint256) public venusAccrued;\n\n /// @notice The Address of VAIController\n VAIControllerInterface public vaiController;\n\n /// @notice The minted VAI amount to each user\n mapping(address => uint256) public mintedVAIs;\n\n /// @notice VAI Mint Rate as a percentage\n uint256 public vaiMintRate;\n\n /**\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\n */\n bool public mintVAIGuardianPaused;\n bool public repayVAIGuardianPaused;\n\n /**\n * @notice Pause/Unpause whole protocol actions\n */\n bool public protocolPaused;\n\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\n uint256 private venusVAIRate;\n}\n\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\n uint256 public venusVAIVaultRate;\n\n // address of VAI Vault\n address public vaiVaultAddress;\n\n // start block of release to VAI Vault\n uint256 public releaseStartBlock;\n\n // minimum release amount to VAI Vault\n uint256 public minReleaseAmount;\n}\n\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\n address public borrowCapGuardian;\n\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address.\n mapping(address => uint256) public borrowCaps;\n}\n\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\n /// @notice Treasury Guardian address\n address public treasuryGuardian;\n\n /// @notice Treasury address\n address public treasuryAddress;\n\n /// @notice Fee percent of accrued interest with decimal 18\n uint256 public treasuryPercent;\n}\n\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\n mapping(address => uint256) private venusContributorSpeeds;\n\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\n mapping(address => uint256) private lastContributorBlock;\n}\n\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\n address public liquidatorContract;\n}\n\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\n ComptrollerLensInterface public comptrollerLens;\n}\n\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\n mapping(address => uint256) public supplyCaps;\n}\n\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\n /// @notice AccessControlManager address\n address internal accessControl;\n\n /// @notice True if a certain action is paused on a certain market\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\n}\n\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\n mapping(address => uint256) public venusBorrowSpeeds;\n\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\n mapping(address => uint256) public venusSupplySpeeds;\n}\n\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\n mapping(address => mapping(address => bool)) public approvedDelegates;\n}\n\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\n mapping(address => bool) public isForcedLiquidationEnabled;\n}\n\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\n }\n\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\n // facet addresses\n address[] internal _facetAddresses;\n}\n\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\n /// @notice Prime token address\n IPrime public prime;\n}\n\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\n}\n\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\n /// @notice The XVS token contract address\n address internal xvs;\n\n /// @notice The XVS vToken contract address\n address internal xvsVToken;\n}\n" + }, + "contracts/Comptroller/Diamond/Diamond.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\npragma experimental ABIEncoderV2;\n\nimport { IDiamondCut } from \"./interfaces/IDiamondCut.sol\";\nimport { Unitroller, ComptrollerV16Storage } from \"../Unitroller.sol\";\n\n/**\n * @title Diamond\n * @author Venus\n * @notice This contract contains functions related to facets\n */\ncontract Diamond is IDiamondCut, ComptrollerV16Storage {\n /// @notice Emitted when functions are added, replaced or removed to facets\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut);\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /**\n * @notice Call _acceptImplementation to accept the diamond proxy as new implementaion\n * @param unitroller Address of the unitroller\n */\n function _become(Unitroller unitroller) public {\n require(msg.sender == unitroller.admin(), \"only unitroller admin can\");\n require(unitroller._acceptImplementation() == 0, \"not authorized\");\n }\n\n /**\n * @notice To add function selectors to the facet's mapping\n * @dev Allows the contract admin to add function selectors\n * @param diamondCut_ IDiamondCut contains facets address, action and function selectors\n */\n function diamondCut(IDiamondCut.FacetCut[] memory diamondCut_) public {\n require(msg.sender == admin, \"only unitroller admin can\");\n libDiamondCut(diamondCut_);\n }\n\n /**\n * @notice Get all function selectors mapped to the facet address\n * @param facet Address of the facet\n * @return selectors Array of function selectors\n */\n function facetFunctionSelectors(address facet) external view returns (bytes4[] memory) {\n return _facetFunctionSelectors[facet].functionSelectors;\n }\n\n /**\n * @notice Get facet position in the _facetFunctionSelectors through facet address\n * @param facet Address of the facet\n * @return Position of the facet\n */\n function facetPosition(address facet) external view returns (uint256) {\n return _facetFunctionSelectors[facet].facetAddressPosition;\n }\n\n /**\n * @notice Get all facet addresses\n * @return facetAddresses Array of facet addresses\n */\n function facetAddresses() external view returns (address[] memory) {\n return _facetAddresses;\n }\n\n /**\n * @notice Get facet address and position through function selector\n * @param functionSelector function selector\n * @return FacetAddressAndPosition facet address and position\n */\n function facetAddress(\n bytes4 functionSelector\n ) external view returns (ComptrollerV16Storage.FacetAddressAndPosition memory) {\n return _selectorToFacetAndPosition[functionSelector];\n }\n\n /**\n * @notice Get all facets address and their function selector\n * @return facets_ Array of Facet\n */\n function facets() external view returns (Facet[] memory) {\n uint256 facetsLength = _facetAddresses.length;\n Facet[] memory facets_ = new Facet[](facetsLength);\n for (uint256 i; i < facetsLength; ++i) {\n address facet = _facetAddresses[i];\n facets_[i].facetAddress = facet;\n facets_[i].functionSelectors = _facetFunctionSelectors[facet].functionSelectors;\n }\n return facets_;\n }\n\n /**\n * @notice To add function selectors to the facets' mapping\n * @param diamondCut_ IDiamondCut contains facets address, action and function selectors\n */\n function libDiamondCut(IDiamondCut.FacetCut[] memory diamondCut_) internal {\n uint256 diamondCutLength = diamondCut_.length;\n for (uint256 facetIndex; facetIndex < diamondCutLength; ++facetIndex) {\n IDiamondCut.FacetCutAction action = diamondCut_[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(diamondCut_);\n }\n\n /**\n * @notice Add function selectors to the facet's address mapping\n * @param facetAddress Address of the facet\n * @param functionSelectors Array of function selectors need to add in the mapping\n */\n function addFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {\n require(functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n require(facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(_facetFunctionSelectors[facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(facetAddress);\n }\n uint256 functionSelectorsLength = functionSelectors.length;\n for (uint256 selectorIndex; selectorIndex < functionSelectorsLength; ++selectorIndex) {\n bytes4 selector = functionSelectors[selectorIndex];\n address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(selector, selectorPosition, facetAddress);\n ++selectorPosition;\n }\n }\n\n /**\n * @notice Replace facet's address mapping for function selectors i.e selectors already associate to any other existing facet\n * @param facetAddress Address of the facet\n * @param functionSelectors Array of function selectors need to replace in the mapping\n */\n function replaceFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {\n require(functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n require(facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(_facetFunctionSelectors[facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(facetAddress);\n }\n uint256 functionSelectorsLength = functionSelectors.length;\n for (uint256 selectorIndex; selectorIndex < functionSelectorsLength; ++selectorIndex) {\n bytes4 selector = functionSelectors[selectorIndex];\n address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(oldFacetAddress, selector);\n addFunction(selector, selectorPosition, facetAddress);\n ++selectorPosition;\n }\n }\n\n /**\n * @notice Remove function selectors to the facet's address mapping\n * @param facetAddress Address of the facet\n * @param functionSelectors Array of function selectors need to remove in the mapping\n */\n function removeFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {\n uint256 functionSelectorsLength = functionSelectors.length;\n require(functionSelectorsLength != 0, \"LibDiamondCut: No selectors in facet to cut\");\n // if function does not exist then do nothing and revert\n require(facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < functionSelectorsLength; ++selectorIndex) {\n bytes4 selector = functionSelectors[selectorIndex];\n address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(oldFacetAddress, selector);\n }\n }\n\n /**\n * @notice Add new facet to the proxy\n * @param facetAddress Address of the facet\n */\n function addFacet(address facetAddress) internal {\n enforceHasContractCode(facetAddress, \"Diamond: New facet has no code\");\n _facetFunctionSelectors[facetAddress].facetAddressPosition = _facetAddresses.length;\n _facetAddresses.push(facetAddress);\n }\n\n /**\n * @notice Add function selector to the facet's address mapping\n * @param selector funciton selector need to be added\n * @param selectorPosition funciton selector position\n * @param facetAddress Address of the facet\n */\n function addFunction(bytes4 selector, uint96 selectorPosition, address facetAddress) internal {\n _selectorToFacetAndPosition[selector].functionSelectorPosition = selectorPosition;\n _facetFunctionSelectors[facetAddress].functionSelectors.push(selector);\n _selectorToFacetAndPosition[selector].facetAddress = facetAddress;\n }\n\n /**\n * @notice Remove function selector to the facet's address mapping\n * @param facetAddress Address of the facet\n * @param selector function selectors need to remove in the mapping\n */\n function removeFunction(address facetAddress, bytes4 selector) internal {\n require(facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = _selectorToFacetAndPosition[selector].functionSelectorPosition;\n uint256 lastSelectorPosition = _facetFunctionSelectors[facetAddress].functionSelectors.length - 1;\n // if not the same then replace selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = _facetFunctionSelectors[facetAddress].functionSelectors[lastSelectorPosition];\n _facetFunctionSelectors[facetAddress].functionSelectors[selectorPosition] = lastSelector;\n _selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n _facetFunctionSelectors[facetAddress].functionSelectors.pop();\n delete _selectorToFacetAndPosition[selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = _facetAddresses.length - 1;\n uint256 facetAddressPosition = _facetFunctionSelectors[facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = _facetAddresses[lastFacetAddressPosition];\n _facetAddresses[facetAddressPosition] = lastFacetAddress;\n _facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n _facetAddresses.pop();\n delete _facetFunctionSelectors[facetAddress];\n }\n }\n\n /**\n * @dev Ensure that the given address has contract code deployed\n * @param _contract The address to check for contract code\n * @param _errorMessage The error message to display if the contract code is not deployed\n */\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize != 0, _errorMessage);\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n function() external payable {\n address facet = _selectorToFacetAndPosition[msg.sig].facetAddress;\n require(facet != address(0), \"Diamond: Function does not exist\");\n // Execute public function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n}\n" + }, + "contracts/Comptroller/Diamond/DiamondConsolidated.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"./facets/MarketFacet.sol\";\nimport \"./facets/PolicyFacet.sol\";\nimport \"./facets/RewardFacet.sol\";\nimport \"./facets/SetterFacet.sol\";\nimport \"./Diamond.sol\";\n\n/**\n * @title DiamondConsolidated\n * @author Venus\n * @notice This contract contains the functions defined in the different facets of the Diamond, plus the getters to the public variables.\n * This contract cannot be deployed, due to its size. Its main purpose is to allow the easy generation of an ABI and the typechain to interact with the\n * Unitroller contract in a simple way\n */\ncontract DiamondConsolidated is Diamond, MarketFacet, PolicyFacet, RewardFacet, SetterFacet {}\n" + }, + "contracts/Comptroller/Diamond/facets/FacetBase.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { IVAIVault } from \"../../../Comptroller/ComptrollerInterface.sol\";\nimport { ComptrollerV16Storage } from \"../../../Comptroller/ComptrollerStorage.sol\";\nimport { IAccessControlManagerV5 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\";\n\nimport { SafeBEP20, IBEP20 } from \"../../../Utils/SafeBEP20.sol\";\n\n/**\n * @title FacetBase\n * @author Venus\n * @notice This facet contract contains functions related to access and checks\n */\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\n using SafeBEP20 for IBEP20;\n\n /// @notice The initial Venus index for a market\n uint224 public constant venusInitialIndex = 1e36;\n // closeFactorMantissa must be strictly greater than this value\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\n // closeFactorMantissa must not exceed this value\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\n // No collateralFactorMantissa may exceed this value\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\n\n /// @notice Emitted when an account enters a market\n event MarketEntered(VToken indexed vToken, address indexed account);\n\n /// @notice Emitted when XVS is distributed to VAI Vault\n event DistributedVAIVaultVenus(uint256 amount);\n\n /// @notice Reverts if the protocol is paused\n function checkProtocolPauseState() internal view {\n require(!protocolPaused, \"protocol is paused\");\n }\n\n /// @notice Reverts if a certain action is paused on a market\n function checkActionPauseState(address market, Action action) internal view {\n require(!actionPaused(market, action), \"action is paused\");\n }\n\n /// @notice Reverts if the caller is not admin\n function ensureAdmin() internal view {\n require(msg.sender == admin, \"only admin can\");\n }\n\n /// @notice Checks the passed address is nonzero\n function ensureNonzeroAddress(address someone) internal pure {\n require(someone != address(0), \"can't be zero address\");\n }\n\n /// @notice Reverts if the market is not listed\n function ensureListed(Market storage market) internal view {\n require(market.isListed, \"market not listed\");\n }\n\n /// @notice Reverts if the caller is neither admin nor the passed address\n function ensureAdminOr(address privilegedAddress) internal view {\n require(msg.sender == admin || msg.sender == privilegedAddress, \"access denied\");\n }\n\n /// @notice Checks the caller is allowed to call the specified fuction\n function ensureAllowed(string memory functionSig) internal view {\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \"access denied\");\n }\n\n /**\n * @notice Checks if a certain action is paused on a market\n * @param action Action id\n * @param market vToken address\n */\n function actionPaused(address market, Action action) public view returns (bool) {\n return _actionPaused[market][uint256(action)];\n }\n\n /**\n * @notice Get the latest block number\n */\n function getBlockNumber() internal view returns (uint256) {\n return block.number;\n }\n\n /**\n * @notice Get the latest block number with the safe32 check\n */\n function getBlockNumberAsUint32() internal view returns (uint32) {\n return safe32(getBlockNumber(), \"block # > 32 bits\");\n }\n\n /**\n * @notice Transfer XVS to VAI Vault\n */\n function releaseToVault() internal {\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\n return;\n }\n\n IBEP20 xvs_ = IBEP20(xvs);\n\n uint256 xvsBalance = xvs_.balanceOf(address(this));\n if (xvsBalance == 0) {\n return;\n }\n\n uint256 actualAmount;\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\n // releaseAmount = venusVAIVaultRate * deltaBlocks\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\n\n if (xvsBalance >= releaseAmount_) {\n actualAmount = releaseAmount_;\n } else {\n actualAmount = xvsBalance;\n }\n\n if (actualAmount < minReleaseAmount) {\n return;\n }\n\n releaseStartBlock = getBlockNumber();\n\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\n emit DistributedVAIVaultVenus(actualAmount);\n\n IVAIVault(vaiVaultAddress).updatePendingRewards();\n }\n\n /**\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\n * @param vTokenModify The market to hypothetically redeem/borrow in\n * @param account The account to determine liquidity for\n * @param redeemTokens The number of tokens to hypothetically redeem\n * @param borrowAmount The amount of underlying to hypothetically borrow\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\n * without calculating accumulated interest.\n * @return (possible error code,\n hypothetical account liquidity in excess of collateral requirements,\n * hypothetical account shortfall below collateral requirements)\n */\n function getHypotheticalAccountLiquidityInternal(\n address account,\n VToken vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n ) internal view returns (Error, uint256, uint256) {\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\n address(this),\n account,\n vTokenModify,\n redeemTokens,\n borrowAmount\n );\n return (Error(err), liquidity, shortfall);\n }\n\n /**\n * @notice Add the market to the borrower's \"assets in\" for liquidity calculations\n * @param vToken The market to enter\n * @param borrower The address of the account to modify\n * @return Success indicator for whether the market was entered\n */\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\n Market storage marketToJoin = markets[address(vToken)];\n ensureListed(marketToJoin);\n if (marketToJoin.accountMembership[borrower]) {\n // already joined\n return Error.NO_ERROR;\n }\n // survived the gauntlet, add to list\n // NOTE: we store these somewhat redundantly as a significant optimization\n // this avoids having to iterate through the list for the most common use cases\n // that is, only when we need to perform liquidity checks\n // and not whenever we want to check if an account is in a particular market\n marketToJoin.accountMembership[borrower] = true;\n accountAssets[borrower].push(vToken);\n\n emit MarketEntered(vToken, borrower);\n\n return Error.NO_ERROR;\n }\n\n /**\n * @notice Checks for the user is allowed to redeem tokens\n * @param vToken Address of the market\n * @param redeemer Address of the user\n * @param redeemTokens Amount of tokens to redeem\n * @return Success indicator for redeem is allowed or not\n */\n function redeemAllowedInternal(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) internal view returns (uint256) {\n ensureListed(markets[vToken]);\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\n if (!markets[vToken].accountMembership[redeemer]) {\n return uint256(Error.NO_ERROR);\n }\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\n redeemer,\n VToken(vToken),\n redeemTokens,\n 0\n );\n if (err != Error.NO_ERROR) {\n return uint256(err);\n }\n if (shortfall != 0) {\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\n }\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Returns the XVS address\n * @return The address of XVS token\n */\n function getXVSAddress() external view returns (address) {\n return xvs;\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/MarketFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { IMarketFacet } from \"../interfaces/IMarketFacet.sol\";\nimport { FacetBase } from \"./FacetBase.sol\";\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\n\n/**\n * @title MarketFacet\n * @author Venus\n * @dev This facet contains all the methods related to the market's management in the pool\n * @notice This facet contract contains functions regarding markets\n */\ncontract MarketFacet is IMarketFacet, FacetBase {\n /// @notice Emitted when an admin supports a market\n event MarketListed(VToken indexed vToken);\n\n /// @notice Emitted when an account exits a market\n event MarketExited(VToken indexed vToken, address indexed account);\n\n /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account\n event DelegateUpdated(address indexed approver, address indexed delegate, bool approved);\n\n /// @notice Emitted when an admin unlists a market\n event MarketUnlisted(address indexed vToken);\n\n /// @notice Indicator that this is a Comptroller contract (for inspection)\n function isComptroller() public pure returns (bool) {\n return true;\n }\n\n /**\n * @notice Returns the assets an account has entered\n * @param account The address of the account to pull assets for\n * @return A dynamic list with the assets the account has entered\n */\n function getAssetsIn(address account) external view returns (VToken[] memory) {\n uint256 len;\n VToken[] memory _accountAssets = accountAssets[account];\n uint256 _accountAssetsLength = _accountAssets.length;\n\n VToken[] memory assetsIn = new VToken[](_accountAssetsLength);\n\n for (uint256 i; i < _accountAssetsLength; ++i) {\n Market memory market = markets[address(_accountAssets[i])];\n if (market.isListed) {\n assetsIn[len] = _accountAssets[i];\n ++len;\n }\n }\n\n assembly {\n mstore(assetsIn, len)\n }\n\n return assetsIn;\n }\n\n /**\n * @notice Return all of the markets\n * @dev The automatic getter may be used to access an individual market\n * @return The list of market addresses\n */\n function getAllMarkets() external view returns (VToken[] memory) {\n return allMarkets;\n }\n\n /**\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\n * @param vTokenBorrowed The address of the borrowed vToken\n * @param vTokenCollateral The address of the collateral vToken\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\n */\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view returns (uint256, uint256) {\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateCalculateSeizeTokens(\n address(this),\n vTokenBorrowed,\n vTokenCollateral,\n actualRepayAmount\n );\n return (err, seizeTokens);\n }\n\n /**\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\n * @param vTokenCollateral The address of the collateral vToken\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\n */\n function liquidateVAICalculateSeizeTokens(\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view returns (uint256, uint256) {\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateVAICalculateSeizeTokens(\n address(this),\n vTokenCollateral,\n actualRepayAmount\n );\n return (err, seizeTokens);\n }\n\n /**\n * @notice Returns whether the given account is entered in the given asset\n * @param account The address of the account to check\n * @param vToken The vToken to check\n * @return True if the account is in the asset, otherwise false\n */\n function checkMembership(address account, VToken vToken) external view returns (bool) {\n return markets[address(vToken)].accountMembership[account];\n }\n\n /**\n * @notice Add assets to be included in account liquidity calculation\n * @param vTokens The list of addresses of the vToken markets to be enabled\n * @return Success indicator for whether each corresponding market was entered\n */\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory) {\n uint256 len = vTokens.length;\n\n uint256[] memory results = new uint256[](len);\n for (uint256 i; i < len; ++i) {\n results[i] = uint256(addToMarketInternal(VToken(vTokens[i]), msg.sender));\n }\n\n return results;\n }\n\n /**\n * @notice Unlist a market by setting isListed to false\n * @dev Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0\n * @param market The address of the market (vToken) to unlist\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\n */\n function unlistMarket(address market) external returns (uint256) {\n ensureAllowed(\"unlistMarket(address)\");\n\n Market storage _market = markets[market];\n\n if (!_market.isListed) {\n return fail(Error.MARKET_NOT_LISTED, FailureInfo.UNLIST_MARKET_NOT_LISTED);\n }\n\n require(actionPaused(market, Action.BORROW), \"borrow action is not paused\");\n require(actionPaused(market, Action.MINT), \"mint action is not paused\");\n require(actionPaused(market, Action.REDEEM), \"redeem action is not paused\");\n require(actionPaused(market, Action.REPAY), \"repay action is not paused\");\n require(actionPaused(market, Action.ENTER_MARKET), \"enter market action is not paused\");\n require(actionPaused(market, Action.LIQUIDATE), \"liquidate action is not paused\");\n require(actionPaused(market, Action.SEIZE), \"seize action is not paused\");\n require(actionPaused(market, Action.TRANSFER), \"transfer action is not paused\");\n require(actionPaused(market, Action.EXIT_MARKET), \"exit market action is not paused\");\n\n require(borrowCaps[market] == 0, \"borrow cap is not 0\");\n require(supplyCaps[market] == 0, \"supply cap is not 0\");\n\n require(_market.collateralFactorMantissa == 0, \"collateral factor is not 0\");\n\n _market.isListed = false;\n emit MarketUnlisted(market);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Removes asset from sender's account liquidity calculation\n * @dev Sender must not have an outstanding borrow balance in the asset,\n * or be providing necessary collateral for an outstanding borrow\n * @param vTokenAddress The address of the asset to be removed\n * @return Whether or not the account successfully exited the market\n */\n function exitMarket(address vTokenAddress) external returns (uint256) {\n checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\n\n VToken vToken = VToken(vTokenAddress);\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\n (uint256 oErr, uint256 tokensHeld, uint256 amountOwed, ) = vToken.getAccountSnapshot(msg.sender);\n require(oErr == 0, \"getAccountSnapshot failed\"); // semi-opaque error code\n\n /* Fail if the sender has a borrow balance */\n if (amountOwed != 0) {\n return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED);\n }\n\n /* Fail if the sender is not permitted to redeem all of their tokens */\n uint256 allowed = redeemAllowedInternal(vTokenAddress, msg.sender, tokensHeld);\n if (allowed != 0) {\n return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed);\n }\n\n Market storage marketToExit = markets[address(vToken)];\n\n /* Return true if the sender is not already ‘in’ the market */\n if (!marketToExit.accountMembership[msg.sender]) {\n return uint256(Error.NO_ERROR);\n }\n\n /* Set vToken account membership to false */\n delete marketToExit.accountMembership[msg.sender];\n\n /* Delete vToken from the account’s list of assets */\n // In order to delete vToken, copy last item in list to location of item to be removed, reduce length by 1\n VToken[] storage userAssetList = accountAssets[msg.sender];\n uint256 len = userAssetList.length;\n uint256 i;\n for (; i < len; ++i) {\n if (userAssetList[i] == vToken) {\n userAssetList[i] = userAssetList[len - 1];\n userAssetList.length--;\n break;\n }\n }\n\n // We *must* have found the asset in the list or our redundant data structure is broken\n assert(i < len);\n\n emit MarketExited(vToken, msg.sender);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Add the market to the markets mapping and set it as listed\n * @dev Allows a privileged role to add and list markets to the Comptroller\n * @param vToken The address of the market (token) to list\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\n */\n function _supportMarket(VToken vToken) external returns (uint256) {\n ensureAllowed(\"_supportMarket(address)\");\n\n if (markets[address(vToken)].isListed) {\n return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS);\n }\n\n vToken.isVToken(); // Sanity check to make sure its really a VToken\n\n // Note that isVenus is not in active use anymore\n Market storage newMarket = markets[address(vToken)];\n newMarket.isListed = true;\n newMarket.isVenus = false;\n newMarket.collateralFactorMantissa = 0;\n\n _addMarketInternal(vToken);\n _initializeMarket(address(vToken));\n\n emit MarketListed(vToken);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account\n * If allowed, the delegate will be able to borrow funds on behalf of the sender\n * Upon a delegated borrow, the delegate will receive the funds, and the borrower\n * will see the debt on their account\n * Upon a delegated redeem, the delegate will receive the redeemed amount and the approver\n * will see a deduction in his vToken balance\n * @param delegate The address to update the rights for\n * @param approved Whether to grant (true) or revoke (false) the borrowing or redeeming rights\n */\n function updateDelegate(address delegate, bool approved) external {\n ensureNonzeroAddress(delegate);\n require(approvedDelegates[msg.sender][delegate] != approved, \"Delegation status unchanged\");\n\n _updateDelegate(msg.sender, delegate, approved);\n }\n\n function _updateDelegate(address approver, address delegate, bool approved) internal {\n approvedDelegates[approver][delegate] = approved;\n emit DelegateUpdated(approver, delegate, approved);\n }\n\n function _addMarketInternal(VToken vToken) internal {\n uint256 allMarketsLength = allMarkets.length;\n for (uint256 i; i < allMarketsLength; ++i) {\n require(allMarkets[i] != vToken, \"already added\");\n }\n allMarkets.push(vToken);\n }\n\n function _initializeMarket(address vToken) internal {\n uint32 blockNumber = getBlockNumberAsUint32();\n\n VenusMarketState storage supplyState = venusSupplyState[vToken];\n VenusMarketState storage borrowState = venusBorrowState[vToken];\n\n /*\n * Update market state indices\n */\n if (supplyState.index == 0) {\n // Initialize supply state index with default value\n supplyState.index = venusInitialIndex;\n }\n\n if (borrowState.index == 0) {\n // Initialize borrow state index with default value\n borrowState.index = venusInitialIndex;\n }\n\n /*\n * Update market state block numbers\n */\n supplyState.block = borrowState.block = blockNumber;\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/PolicyFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { IPolicyFacet } from \"../interfaces/IPolicyFacet.sol\";\n\nimport { XVSRewardsHelper } from \"./XVSRewardsHelper.sol\";\n\n/**\n * @title PolicyFacet\n * @author Venus\n * @dev This facet contains all the hooks used while transferring the assets\n * @notice This facet contract contains all the external pre-hook functions related to vToken\n */\ncontract PolicyFacet is IPolicyFacet, XVSRewardsHelper {\n /// @notice Emitted when a new borrow-side XVS speed is calculated for a market\n event VenusBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /// @notice Emitted when a new supply-side XVS speed is calculated for a market\n event VenusSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /**\n * @notice Checks if the account should be allowed to mint tokens in the given market\n * @param vToken The market to verify the mint against\n * @param minter The account which would get the minted tokens\n * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens\n * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256) {\n // Pausing is a very serious situation - we revert to sound the alarms\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.MINT);\n ensureListed(markets[vToken]);\n\n uint256 supplyCap = supplyCaps[vToken];\n require(supplyCap != 0, \"market supply cap is 0\");\n\n uint256 vTokenSupply = VToken(vToken).totalSupply();\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\n require(nextTotalSupply <= supplyCap, \"market supply cap reached\");\n\n // Keep the flywheel moving\n updateVenusSupplyIndex(vToken);\n distributeSupplierVenus(vToken, minter);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset being minted\n * @param minter The address minting the tokens\n * @param actualMintAmount The amount of the underlying asset being minted\n * @param mintTokens The number of tokens being minted\n */\n // solhint-disable-next-line no-unused-vars\n function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(minter, vToken);\n }\n }\n\n /**\n * @notice Checks if the account should be allowed to redeem tokens in the given market\n * @param vToken The market to verify the redeem against\n * @param redeemer The account which would redeem the tokens\n * @param redeemTokens The number of vTokens to exchange for the underlying asset in the market\n * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256) {\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.REDEEM);\n\n uint256 allowed = redeemAllowedInternal(vToken, redeemer, redeemTokens);\n if (allowed != uint256(Error.NO_ERROR)) {\n return allowed;\n }\n\n // Keep the flywheel moving\n updateVenusSupplyIndex(vToken);\n distributeSupplierVenus(vToken, redeemer);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset being redeemed\n * @param redeemer The address redeeming the tokens\n * @param redeemAmount The amount of the underlying asset being redeemed\n * @param redeemTokens The number of tokens being redeemed\n */\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {\n require(redeemTokens != 0 || redeemAmount == 0, \"redeemTokens zero\");\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(redeemer, vToken);\n }\n }\n\n /**\n * @notice Checks if the account should be allowed to borrow the underlying asset of the given market\n * @param vToken The market to verify the borrow against\n * @param borrower The account which would borrow the asset\n * @param borrowAmount The amount of underlying the account would borrow\n * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256) {\n // Pausing is a very serious situation - we revert to sound the alarms\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.BORROW);\n ensureListed(markets[vToken]);\n\n uint256 borrowCap = borrowCaps[vToken];\n require(borrowCap != 0, \"market borrow cap is 0\");\n\n if (!markets[vToken].accountMembership[borrower]) {\n // only vTokens may call borrowAllowed if borrower not in market\n require(msg.sender == vToken, \"sender must be vToken\");\n\n // attempt to add borrower to the market\n Error err = addToMarketInternal(VToken(vToken), borrower);\n if (err != Error.NO_ERROR) {\n return uint256(err);\n }\n }\n\n if (oracle.getUnderlyingPrice(VToken(vToken)) == 0) {\n return uint256(Error.PRICE_ERROR);\n }\n\n uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount);\n require(nextTotalBorrows <= borrowCap, \"market borrow cap reached\");\n\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\n borrower,\n VToken(vToken),\n 0,\n borrowAmount\n );\n if (err != Error.NO_ERROR) {\n return uint256(err);\n }\n if (shortfall != 0) {\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\n }\n\n // Keep the flywheel moving\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n updateVenusBorrowIndex(vToken, borrowIndex);\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset whose underlying is being borrowed\n * @param borrower The address borrowing the underlying\n * @param borrowAmount The amount of the underlying asset requested to borrow\n */\n // solhint-disable-next-line no-unused-vars\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(borrower, vToken);\n }\n }\n\n /**\n * @notice Checks if the account should be allowed to repay a borrow in the given market\n * @param vToken The market to verify the repay against\n * @param payer The account which would repay the asset\n * @param borrower The account which borrowed the asset\n * @param repayAmount The amount of the underlying asset the account would repay\n * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function repayBorrowAllowed(\n address vToken,\n address payer, // solhint-disable-line no-unused-vars\n address borrower,\n uint256 repayAmount // solhint-disable-line no-unused-vars\n ) external returns (uint256) {\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.REPAY);\n ensureListed(markets[vToken]);\n\n // Keep the flywheel moving\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n updateVenusBorrowIndex(vToken, borrowIndex);\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset being repaid\n * @param payer The address repaying the borrow\n * @param borrower The address of the borrower\n * @param actualRepayAmount The amount of underlying being repaid\n */\n function repayBorrowVerify(\n address vToken,\n address payer, // solhint-disable-line no-unused-vars\n address borrower,\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\n uint256 borrowerIndex // solhint-disable-line no-unused-vars\n ) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(borrower, vToken);\n }\n }\n\n /**\n * @notice Checks if the liquidation should be allowed to occur\n * @param vTokenBorrowed Asset which was borrowed by the borrower\n * @param vTokenCollateral Asset which was used as collateral and will be seized\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @param repayAmount The amount of underlying being repaid\n */\n function liquidateBorrowAllowed(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint256 repayAmount\n ) external view returns (uint256) {\n checkProtocolPauseState();\n\n // if we want to pause liquidating to vTokenCollateral, we should pause seizing\n checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\n\n if (liquidatorContract != address(0) && liquidator != liquidatorContract) {\n return uint256(Error.UNAUTHORIZED);\n }\n\n ensureListed(markets[vTokenCollateral]);\n\n uint256 borrowBalance;\n if (address(vTokenBorrowed) != address(vaiController)) {\n ensureListed(markets[vTokenBorrowed]);\n borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\n } else {\n borrowBalance = vaiController.getVAIRepayAmount(borrower);\n }\n\n if (isForcedLiquidationEnabled[vTokenBorrowed] || isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed]) {\n if (repayAmount > borrowBalance) {\n return uint(Error.TOO_MUCH_REPAY);\n }\n return uint(Error.NO_ERROR);\n }\n\n /* The borrower must have shortfall in order to be liquidatable */\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(borrower, VToken(address(0)), 0, 0);\n if (err != Error.NO_ERROR) {\n return uint256(err);\n }\n if (shortfall == 0) {\n return uint256(Error.INSUFFICIENT_SHORTFALL);\n }\n\n // The liquidator may not repay more than what is allowed by the closeFactor\n //-- maxClose = multipy of closeFactorMantissa and borrowBalance\n if (repayAmount > mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance)) {\n return uint256(Error.TOO_MUCH_REPAY);\n }\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vTokenBorrowed Asset which was borrowed by the borrower\n * @param vTokenCollateral Asset which was used as collateral and will be seized\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @param actualRepayAmount The amount of underlying being repaid\n * @param seizeTokens The amount of collateral token that will be seized\n */\n function liquidateBorrowVerify(\n address vTokenBorrowed,\n address vTokenCollateral, // solhint-disable-line no-unused-vars\n address liquidator,\n address borrower,\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\n uint256 seizeTokens // solhint-disable-line no-unused-vars\n ) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(borrower, vTokenBorrowed);\n prime.accrueInterestAndUpdateScore(liquidator, vTokenBorrowed);\n }\n }\n\n /**\n * @notice Checks if the seizing of assets should be allowed to occur\n * @param vTokenCollateral Asset which was used as collateral and will be seized\n * @param vTokenBorrowed Asset which was borrowed by the borrower\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @param seizeTokens The number of collateral tokens to seize\n */\n function seizeAllowed(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint256 seizeTokens // solhint-disable-line no-unused-vars\n ) external returns (uint256) {\n // Pausing is a very serious situation - we revert to sound the alarms\n checkProtocolPauseState();\n checkActionPauseState(vTokenCollateral, Action.SEIZE);\n\n Market storage market = markets[vTokenCollateral];\n\n // We've added VAIController as a borrowed token list check for seize\n ensureListed(market);\n\n if (!market.accountMembership[borrower]) {\n return uint256(Error.MARKET_NOT_COLLATERAL);\n }\n\n if (address(vTokenBorrowed) != address(vaiController)) {\n ensureListed(markets[vTokenBorrowed]);\n }\n\n if (VToken(vTokenCollateral).comptroller() != VToken(vTokenBorrowed).comptroller()) {\n return uint256(Error.COMPTROLLER_MISMATCH);\n }\n\n // Keep the flywheel moving\n updateVenusSupplyIndex(vTokenCollateral);\n distributeSupplierVenus(vTokenCollateral, borrower);\n distributeSupplierVenus(vTokenCollateral, liquidator);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vTokenCollateral Asset which was used as collateral and will be seized\n * @param vTokenBorrowed Asset which was borrowed by the borrower\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @param seizeTokens The number of collateral tokens to seize\n */\n function seizeVerify(\n address vTokenCollateral,\n address vTokenBorrowed, // solhint-disable-line no-unused-vars\n address liquidator,\n address borrower,\n uint256 seizeTokens // solhint-disable-line no-unused-vars\n ) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(borrower, vTokenCollateral);\n prime.accrueInterestAndUpdateScore(liquidator, vTokenCollateral);\n }\n }\n\n /**\n * @notice Checks if the account should be allowed to transfer tokens in the given market\n * @param vToken The market to verify the transfer against\n * @param src The account which sources the tokens\n * @param dst The account which receives the tokens\n * @param transferTokens The number of vTokens to transfer\n * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function transferAllowed(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external returns (uint256) {\n // Pausing is a very serious situation - we revert to sound the alarms\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.TRANSFER);\n\n // Currently the only consideration is whether or not\n // the src is allowed to redeem this many tokens\n uint256 allowed = redeemAllowedInternal(vToken, src, transferTokens);\n if (allowed != uint256(Error.NO_ERROR)) {\n return allowed;\n }\n\n // Keep the flywheel moving\n updateVenusSupplyIndex(vToken);\n distributeSupplierVenus(vToken, src);\n distributeSupplierVenus(vToken, dst);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset being transferred\n * @param src The account which sources the tokens\n * @param dst The account which receives the tokens\n * @param transferTokens The number of vTokens to transfer\n */\n // solhint-disable-next-line no-unused-vars\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(src, vToken);\n prime.accrueInterestAndUpdateScore(dst, vToken);\n }\n }\n\n /**\n * @notice Determine the current account liquidity wrt collateral requirements\n * @return (possible error code (semi-opaque),\n account liquidity in excess of collateral requirements,\n * account shortfall below collateral requirements)\n */\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256) {\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\n account,\n VToken(address(0)),\n 0,\n 0\n );\n\n return (uint256(err), liquidity, shortfall);\n }\n\n /**\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\n * @param vTokenModify The market to hypothetically redeem/borrow in\n * @param account The account to determine liquidity for\n * @param redeemTokens The number of tokens to hypothetically redeem\n * @param borrowAmount The amount of underlying to hypothetically borrow\n * @return (possible error code (semi-opaque),\n hypothetical account liquidity in excess of collateral requirements,\n * hypothetical account shortfall below collateral requirements)\n */\n function getHypotheticalAccountLiquidity(\n address account,\n address vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n ) external view returns (uint256, uint256, uint256) {\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\n account,\n VToken(vTokenModify),\n redeemTokens,\n borrowAmount\n );\n return (uint256(err), liquidity, shortfall);\n }\n\n // setter functionality\n /**\n * @notice Set XVS speed for a single market\n * @dev Allows the contract admin to set XVS speed for a market\n * @param vTokens The market whose XVS speed to update\n * @param supplySpeeds New XVS speed for supply\n * @param borrowSpeeds New XVS speed for borrow\n */\n function _setVenusSpeeds(\n VToken[] calldata vTokens,\n uint256[] calldata supplySpeeds,\n uint256[] calldata borrowSpeeds\n ) external {\n ensureAdmin();\n\n uint256 numTokens = vTokens.length;\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \"invalid input\");\n\n for (uint256 i; i < numTokens; ++i) {\n ensureNonzeroAddress(address(vTokens[i]));\n setVenusSpeedInternal(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\n }\n }\n\n function setVenusSpeedInternal(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal {\n ensureListed(markets[address(vToken)]);\n\n if (venusSupplySpeeds[address(vToken)] != supplySpeed) {\n // Supply speed updated so let's update supply state to ensure that\n // 1. XVS accrued properly for the old speed, and\n // 2. XVS accrued at the new speed starts after this block.\n\n updateVenusSupplyIndex(address(vToken));\n // Update speed and emit event\n venusSupplySpeeds[address(vToken)] = supplySpeed;\n emit VenusSupplySpeedUpdated(vToken, supplySpeed);\n }\n\n if (venusBorrowSpeeds[address(vToken)] != borrowSpeed) {\n // Borrow speed updated so let's update borrow state to ensure that\n // 1. XVS accrued properly for the old speed, and\n // 2. XVS accrued at the new speed starts after this block.\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n updateVenusBorrowIndex(address(vToken), borrowIndex);\n\n // Update speed and emit event\n venusBorrowSpeeds[address(vToken)] = borrowSpeed;\n emit VenusBorrowSpeedUpdated(vToken, borrowSpeed);\n }\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/RewardFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { IRewardFacet } from \"../interfaces/IRewardFacet.sol\";\nimport { XVSRewardsHelper } from \"./XVSRewardsHelper.sol\";\nimport { SafeBEP20, IBEP20 } from \"../../../Utils/SafeBEP20.sol\";\nimport { VBep20Interface } from \"../../../Tokens/VTokens/VTokenInterfaces.sol\";\n\n/**\n * @title RewardFacet\n * @author Venus\n * @dev This facet contains all the methods related to the reward functionality\n * @notice This facet contract provides the external functions related to all claims and rewards of the protocol\n */\ncontract RewardFacet is IRewardFacet, XVSRewardsHelper {\n /// @notice Emitted when Venus is granted by admin\n event VenusGranted(address indexed recipient, uint256 amount);\n\n /// @notice Emitted when XVS are seized for the holder\n event VenusSeized(address indexed holder, uint256 amount);\n\n using SafeBEP20 for IBEP20;\n\n /**\n * @notice Claim all the xvs accrued by holder in all markets and VAI\n * @param holder The address to claim XVS for\n */\n function claimVenus(address holder) public {\n return claimVenus(holder, allMarkets);\n }\n\n /**\n * @notice Claim all the xvs accrued by holder in the specified markets\n * @param holder The address to claim XVS for\n * @param vTokens The list of markets to claim XVS in\n */\n function claimVenus(address holder, VToken[] memory vTokens) public {\n address[] memory holders = new address[](1);\n holders[0] = holder;\n claimVenus(holders, vTokens, true, true);\n }\n\n /**\n * @notice Claim all xvs accrued by the holders\n * @param holders The addresses to claim XVS for\n * @param vTokens The list of markets to claim XVS in\n * @param borrowers Whether or not to claim XVS earned by borrowing\n * @param suppliers Whether or not to claim XVS earned by supplying\n */\n function claimVenus(address[] memory holders, VToken[] memory vTokens, bool borrowers, bool suppliers) public {\n claimVenus(holders, vTokens, borrowers, suppliers, false);\n }\n\n /**\n * @notice Claim all the xvs accrued by holder in all markets, a shorthand for `claimVenus` with collateral set to `true`\n * @param holder The address to claim XVS for\n */\n function claimVenusAsCollateral(address holder) external {\n address[] memory holders = new address[](1);\n holders[0] = holder;\n claimVenus(holders, allMarkets, true, true, true);\n }\n\n /**\n * @notice Transfer XVS to the user with user's shortfall considered\n * @dev Note: If there is not enough XVS, we do not perform the transfer all\n * @param user The address of the user to transfer XVS to\n * @param amount The amount of XVS to (possibly) transfer\n * @param shortfall The shortfall of the user\n * @param collateral Whether or not we will use user's venus reward as collateral to pay off the debt\n * @return The amount of XVS which was NOT transferred to the user\n */\n function grantXVSInternal(\n address user,\n uint256 amount,\n uint256 shortfall,\n bool collateral\n ) internal returns (uint256) {\n // If the user is blacklisted, they can't get XVS rewards\n require(\n user != 0xEF044206Db68E40520BfA82D45419d498b4bc7Bf &&\n user != 0x7589dD3355DAE848FDbF75044A3495351655cB1A &&\n user != 0x33df7a7F6D44307E1e5F3B15975b47515e5524c0 &&\n user != 0x24e77E5b74B30b026E9996e4bc3329c881e24968,\n \"Blacklisted\"\n );\n\n IBEP20 xvs_ = IBEP20(xvs);\n\n if (amount == 0 || amount > xvs_.balanceOf(address(this))) {\n return amount;\n }\n\n if (shortfall == 0) {\n xvs_.safeTransfer(user, amount);\n return 0;\n }\n // If user's bankrupt and doesn't use pending xvs as collateral, don't grant\n // anything, otherwise, we will transfer the pending xvs as collateral to\n // vXVS token and mint vXVS for the user\n //\n // If mintBehalf failed, don't grant any xvs\n require(collateral, \"bankrupt\");\n\n address xvsVToken_ = xvsVToken;\n\n xvs_.safeApprove(xvsVToken_, 0);\n xvs_.safeApprove(xvsVToken_, amount);\n require(VBep20Interface(xvsVToken_).mintBehalf(user, amount) == uint256(Error.NO_ERROR), \"mint behalf error\");\n\n // set venusAccrued[user] to 0\n return 0;\n }\n\n /*** Venus Distribution Admin ***/\n\n /**\n * @notice Transfer XVS to the recipient\n * @dev Allows the contract admin to transfer XVS to any recipient based on the recipient's shortfall\n * Note: If there is not enough XVS, we do not perform the transfer all\n * @param recipient The address of the recipient to transfer XVS to\n * @param amount The amount of XVS to (possibly) transfer\n */\n function _grantXVS(address recipient, uint256 amount) external {\n ensureAdmin();\n uint256 amountLeft = grantXVSInternal(recipient, amount, 0, false);\n require(amountLeft == 0, \"no xvs\");\n emit VenusGranted(recipient, amount);\n }\n\n /**\n * @dev Seize XVS tokens from the specified holders and transfer to recipient\n * @notice Seize XVS rewards allocated to holders\n * @param holders Addresses of the XVS holders\n * @param recipient Address of the XVS token recipient\n * @return The total amount of XVS tokens seized and transferred to recipient\n */\n function seizeVenus(address[] calldata holders, address recipient) external returns (uint256) {\n ensureAllowed(\"seizeVenus(address[],address)\");\n\n uint256 holdersLength = holders.length;\n uint256 totalHoldings;\n\n updateAndDistributeRewardsInternal(holders, allMarkets, true, true);\n for (uint256 j; j < holdersLength; ++j) {\n address holder = holders[j];\n uint256 userHolding = venusAccrued[holder];\n\n if (userHolding != 0) {\n totalHoldings += userHolding;\n delete venusAccrued[holder];\n }\n\n emit VenusSeized(holder, userHolding);\n }\n\n if (totalHoldings != 0) {\n IBEP20(xvs).safeTransfer(recipient, totalHoldings);\n emit VenusGranted(recipient, totalHoldings);\n }\n\n return totalHoldings;\n }\n\n /**\n * @notice Claim all xvs accrued by the holders\n * @param holders The addresses to claim XVS for\n * @param vTokens The list of markets to claim XVS in\n * @param borrowers Whether or not to claim XVS earned by borrowing\n * @param suppliers Whether or not to claim XVS earned by supplying\n * @param collateral Whether or not to use XVS earned as collateral, only takes effect when the holder has a shortfall\n */\n function claimVenus(\n address[] memory holders,\n VToken[] memory vTokens,\n bool borrowers,\n bool suppliers,\n bool collateral\n ) public {\n uint256 holdersLength = holders.length;\n\n updateAndDistributeRewardsInternal(holders, vTokens, borrowers, suppliers);\n for (uint256 j; j < holdersLength; ++j) {\n address holder = holders[j];\n\n // If there is a positive shortfall, the XVS reward is accrued,\n // but won't be granted to this holder\n (, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(holder, VToken(address(0)), 0, 0);\n\n uint256 value = venusAccrued[holder];\n delete venusAccrued[holder];\n\n uint256 returnAmount = grantXVSInternal(holder, value, shortfall, collateral);\n\n // returnAmount can only be positive if balance of xvsAddress is less than grant amount(venusAccrued[holder])\n if (returnAmount != 0) {\n venusAccrued[holder] = returnAmount;\n }\n }\n }\n\n /**\n * @notice Update and distribute tokens\n * @param holders The addresses to claim XVS for\n * @param vTokens The list of markets to claim XVS in\n * @param borrowers Whether or not to claim XVS earned by borrowing\n * @param suppliers Whether or not to claim XVS earned by supplying\n */\n function updateAndDistributeRewardsInternal(\n address[] memory holders,\n VToken[] memory vTokens,\n bool borrowers,\n bool suppliers\n ) internal {\n uint256 j;\n uint256 holdersLength = holders.length;\n uint256 vTokensLength = vTokens.length;\n\n for (uint256 i; i < vTokensLength; ++i) {\n VToken vToken = vTokens[i];\n ensureListed(markets[address(vToken)]);\n if (borrowers) {\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n updateVenusBorrowIndex(address(vToken), borrowIndex);\n for (j = 0; j < holdersLength; ++j) {\n distributeBorrowerVenus(address(vToken), holders[j], borrowIndex);\n }\n }\n\n if (suppliers) {\n updateVenusSupplyIndex(address(vToken));\n for (j = 0; j < holdersLength; ++j) {\n distributeSupplierVenus(address(vToken), holders[j]);\n }\n }\n }\n }\n\n /**\n * @notice Returns the XVS vToken address\n * @return The address of XVS vToken\n */\n function getXVSVTokenAddress() external view returns (address) {\n return xvsVToken;\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/SetterFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { ISetterFacet } from \"../interfaces/ISetterFacet.sol\";\nimport { PriceOracle } from \"../../../Oracle/PriceOracle.sol\";\nimport { ComptrollerLensInterface } from \"../../ComptrollerLensInterface.sol\";\nimport { VAIControllerInterface } from \"../../../Tokens/VAI/VAIControllerInterface.sol\";\nimport { FacetBase } from \"./FacetBase.sol\";\nimport { IPrime } from \"../../../Tokens/Prime/IPrime.sol\";\n\n/**\n * @title SetterFacet\n * @author Venus\n * @dev This facet contains all the setters for the states\n * @notice This facet contract contains all the configurational setter functions\n */\ncontract SetterFacet is ISetterFacet, FacetBase {\n /// @notice Emitted when close factor is changed by admin\n event NewCloseFactor(uint256 oldCloseFactorMantissa, uint256 newCloseFactorMantissa);\n\n /// @notice Emitted when a collateral factor is changed by admin\n event NewCollateralFactor(\n VToken indexed vToken,\n uint256 oldCollateralFactorMantissa,\n uint256 newCollateralFactorMantissa\n );\n\n /// @notice Emitted when liquidation incentive is changed by admin\n event NewLiquidationIncentive(uint256 oldLiquidationIncentiveMantissa, uint256 newLiquidationIncentiveMantissa);\n\n /// @notice Emitted when price oracle is changed\n event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle);\n\n /// @notice Emitted when borrow cap for a vToken is changed\n event NewBorrowCap(VToken indexed vToken, uint256 newBorrowCap);\n\n /// @notice Emitted when VAIController is changed\n event NewVAIController(VAIControllerInterface oldVAIController, VAIControllerInterface newVAIController);\n\n /// @notice Emitted when VAI mint rate is changed by admin\n event NewVAIMintRate(uint256 oldVAIMintRate, uint256 newVAIMintRate);\n\n /// @notice Emitted when protocol state is changed by admin\n event ActionProtocolPaused(bool state);\n\n /// @notice Emitted when treasury guardian is changed\n event NewTreasuryGuardian(address oldTreasuryGuardian, address newTreasuryGuardian);\n\n /// @notice Emitted when treasury address is changed\n event NewTreasuryAddress(address oldTreasuryAddress, address newTreasuryAddress);\n\n /// @notice Emitted when treasury percent is changed\n event NewTreasuryPercent(uint256 oldTreasuryPercent, uint256 newTreasuryPercent);\n\n /// @notice Emitted when liquidator adress is changed\n event NewLiquidatorContract(address oldLiquidatorContract, address newLiquidatorContract);\n\n /// @notice Emitted when ComptrollerLens address is changed\n event NewComptrollerLens(address oldComptrollerLens, address newComptrollerLens);\n\n /// @notice Emitted when supply cap for a vToken is changed\n event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap);\n\n /// @notice Emitted when access control address is changed by admin\n event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress);\n\n /// @notice Emitted when pause guardian is changed\n event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian);\n\n /// @notice Emitted when an action is paused on a market\n event ActionPausedMarket(VToken indexed vToken, Action indexed action, bool pauseState);\n\n /// @notice Emitted when VAI Vault info is changed\n event NewVAIVaultInfo(address indexed vault_, uint256 releaseStartBlock_, uint256 releaseInterval_);\n\n /// @notice Emitted when Venus VAI Vault rate is changed\n event NewVenusVAIVaultRate(uint256 oldVenusVAIVaultRate, uint256 newVenusVAIVaultRate);\n\n /// @notice Emitted when prime token contract address is changed\n event NewPrimeToken(IPrime oldPrimeToken, IPrime newPrimeToken);\n\n /// @notice Emitted when forced liquidation is enabled or disabled for all users in a market\n event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);\n\n /// @notice Emitted when forced liquidation is enabled or disabled for a user borrowing in a market\n event IsForcedLiquidationEnabledForUserUpdated(address indexed borrower, address indexed vToken, bool enable);\n\n /// @notice Emitted when XVS token address is changed\n event NewXVSToken(address indexed oldXVS, address indexed newXVS);\n\n /// @notice Emitted when XVS vToken address is changed\n event NewXVSVToken(address indexed oldXVSVToken, address indexed newXVSVToken);\n\n /**\n * @notice Compare two addresses to ensure they are different\n * @param oldAddress The original address to compare\n * @param newAddress The new address to compare\n */\n modifier compareAddress(address oldAddress, address newAddress) {\n require(oldAddress != newAddress, \"old address is same as new address\");\n _;\n }\n\n /**\n * @notice Compare two values to ensure they are different\n * @param oldValue The original value to compare\n * @param newValue The new value to compare\n */\n modifier compareValue(uint256 oldValue, uint256 newValue) {\n require(oldValue != newValue, \"old value is same as new value\");\n _;\n }\n\n /**\n * @notice Sets a new price oracle for the comptroller\n * @dev Allows the contract admin to set a new price oracle used by the Comptroller\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPriceOracle(\n PriceOracle newOracle\n ) external compareAddress(address(oracle), address(newOracle)) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n ensureNonzeroAddress(address(newOracle));\n\n // Track the old oracle for the comptroller\n PriceOracle oldOracle = oracle;\n\n // Set comptroller's oracle to newOracle\n oracle = newOracle;\n\n // Emit NewPriceOracle(oldOracle, newOracle)\n emit NewPriceOracle(oldOracle, newOracle);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets the closeFactor used when liquidating borrows\n * @dev Allows the contract admin to set the closeFactor used to liquidate borrows\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\n * @return uint256 0=success, otherwise will revert\n */\n function _setCloseFactor(\n uint256 newCloseFactorMantissa\n ) external compareValue(closeFactorMantissa, newCloseFactorMantissa) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n\n Exp memory newCloseFactorExp = Exp({ mantissa: newCloseFactorMantissa });\n\n //-- Check close factor <= 0.9\n Exp memory highLimit = Exp({ mantissa: closeFactorMaxMantissa });\n //-- Check close factor >= 0.05\n Exp memory lowLimit = Exp({ mantissa: closeFactorMinMantissa });\n\n if (lessThanExp(highLimit, newCloseFactorExp) || greaterThanExp(lowLimit, newCloseFactorExp)) {\n return fail(Error.INVALID_CLOSE_FACTOR, FailureInfo.SET_CLOSE_FACTOR_VALIDATION);\n }\n\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\n closeFactorMantissa = newCloseFactorMantissa;\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Allows the contract admin to set the address of access control of this contract\n * @param newAccessControlAddress New address for the access control\n * @return uint256 0=success, otherwise will revert\n */\n function _setAccessControl(\n address newAccessControlAddress\n ) external compareAddress(accessControl, newAccessControlAddress) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n ensureNonzeroAddress(newAccessControlAddress);\n\n address oldAccessControlAddress = accessControl;\n\n accessControl = newAccessControlAddress;\n emit NewAccessControl(oldAccessControlAddress, newAccessControlAddress);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets the collateralFactor for a market\n * @dev Allows a privileged role to set the collateralFactorMantissa\n * @param vToken The market to set the factor on\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\n */\n function _setCollateralFactor(\n VToken vToken,\n uint256 newCollateralFactorMantissa\n )\n external\n compareValue(markets[address(vToken)].collateralFactorMantissa, newCollateralFactorMantissa)\n returns (uint256)\n {\n // Check caller is allowed by access control manager\n ensureAllowed(\"_setCollateralFactor(address,uint256)\");\n ensureNonzeroAddress(address(vToken));\n\n // Verify market is listed\n Market storage market = markets[address(vToken)];\n ensureListed(market);\n\n Exp memory newCollateralFactorExp = Exp({ mantissa: newCollateralFactorMantissa });\n\n //-- Check collateral factor <= 0.9\n Exp memory highLimit = Exp({ mantissa: collateralFactorMaxMantissa });\n if (lessThanExp(highLimit, newCollateralFactorExp)) {\n return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION);\n }\n\n // If collateral factor != 0, fail if price == 0\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(vToken) == 0) {\n return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE);\n }\n\n // Set market's collateral factor to new collateral factor, remember old value\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\n market.collateralFactorMantissa = newCollateralFactorMantissa;\n\n // Emit event with asset, old collateral factor, and new collateral factor\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets liquidationIncentive\n * @dev Allows a privileged role to set the liquidationIncentiveMantissa\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\n */\n function _setLiquidationIncentive(\n uint256 newLiquidationIncentiveMantissa\n ) external compareValue(liquidationIncentiveMantissa, newLiquidationIncentiveMantissa) returns (uint256) {\n ensureAllowed(\"_setLiquidationIncentive(uint256)\");\n\n require(newLiquidationIncentiveMantissa >= 1e18, \"incentive < 1e18\");\n\n // Save current value for use in log\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\n // Set liquidation incentive to new incentive\n liquidationIncentiveMantissa = newLiquidationIncentiveMantissa;\n\n // Emit event with old incentive, new incentive\n emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Update the address of the liquidator contract\n * @dev Allows the contract admin to update the address of liquidator contract\n * @param newLiquidatorContract_ The new address of the liquidator contract\n */\n function _setLiquidatorContract(\n address newLiquidatorContract_\n ) external compareAddress(liquidatorContract, newLiquidatorContract_) {\n // Check caller is admin\n ensureAdmin();\n ensureNonzeroAddress(newLiquidatorContract_);\n address oldLiquidatorContract = liquidatorContract;\n liquidatorContract = newLiquidatorContract_;\n emit NewLiquidatorContract(oldLiquidatorContract, newLiquidatorContract_);\n }\n\n /**\n * @notice Admin function to change the Pause Guardian\n * @dev Allows the contract admin to change the Pause Guardian\n * @param newPauseGuardian The address of the new Pause Guardian\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\n */\n function _setPauseGuardian(\n address newPauseGuardian\n ) external compareAddress(pauseGuardian, newPauseGuardian) returns (uint256) {\n ensureAdmin();\n ensureNonzeroAddress(newPauseGuardian);\n\n // Save current value for inclusion in log\n address oldPauseGuardian = pauseGuardian;\n // Store pauseGuardian with value newPauseGuardian\n pauseGuardian = newPauseGuardian;\n\n // Emit NewPauseGuardian(OldPauseGuardian, NewPauseGuardian)\n emit NewPauseGuardian(oldPauseGuardian, newPauseGuardian);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\n * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed\n * @param vTokens The addresses of the markets (tokens) to change the borrow caps for\n * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed\n */\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\n ensureAllowed(\"_setMarketBorrowCaps(address[],uint256[])\");\n\n uint256 numMarkets = vTokens.length;\n uint256 numBorrowCaps = newBorrowCaps.length;\n\n require(numMarkets != 0 && numMarkets == numBorrowCaps, \"invalid input\");\n\n for (uint256 i; i < numMarkets; ++i) {\n borrowCaps[address(vTokens[i])] = newBorrowCaps[i];\n emit NewBorrowCap(vTokens[i], newBorrowCaps[i]);\n }\n }\n\n /**\n * @notice Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\n * @dev Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\n * @param vTokens The addresses of the markets (tokens) to change the supply caps for\n * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\n */\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\n ensureAllowed(\"_setMarketSupplyCaps(address[],uint256[])\");\n\n uint256 numMarkets = vTokens.length;\n uint256 numSupplyCaps = newSupplyCaps.length;\n\n require(numMarkets != 0 && numMarkets == numSupplyCaps, \"invalid input\");\n\n for (uint256 i; i < numMarkets; ++i) {\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\n }\n }\n\n /**\n * @notice Set whole protocol pause/unpause state\n * @dev Allows a privileged role to pause/unpause protocol\n * @param state The new state (true=paused, false=unpaused)\n * @return bool The updated state of the protocol\n */\n function _setProtocolPaused(bool state) external returns (bool) {\n ensureAllowed(\"_setProtocolPaused(bool)\");\n\n protocolPaused = state;\n emit ActionProtocolPaused(state);\n return state;\n }\n\n /**\n * @notice Pause/unpause certain actions\n * @dev Allows a privileged role to pause/unpause the protocol action state\n * @param markets_ Markets to pause/unpause the actions on\n * @param actions_ List of action ids to pause/unpause\n * @param paused_ The new paused state (true=paused, false=unpaused)\n */\n function _setActionsPaused(address[] calldata markets_, Action[] calldata actions_, bool paused_) external {\n ensureAllowed(\"_setActionsPaused(address[],uint8[],bool)\");\n\n uint256 numMarkets = markets_.length;\n uint256 numActions = actions_.length;\n for (uint256 marketIdx; marketIdx < numMarkets; ++marketIdx) {\n for (uint256 actionIdx; actionIdx < numActions; ++actionIdx) {\n setActionPausedInternal(markets_[marketIdx], actions_[actionIdx], paused_);\n }\n }\n }\n\n /**\n * @dev Pause/unpause an action on a market\n * @param market Market to pause/unpause the action on\n * @param action Action id to pause/unpause\n * @param paused The new paused state (true=paused, false=unpaused)\n */\n function setActionPausedInternal(address market, Action action, bool paused) internal {\n ensureListed(markets[market]);\n _actionPaused[market][uint256(action)] = paused;\n emit ActionPausedMarket(VToken(market), action, paused);\n }\n\n /**\n * @notice Sets a new VAI controller\n * @dev Admin function to set a new VAI controller\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setVAIController(\n VAIControllerInterface vaiController_\n ) external compareAddress(address(vaiController), address(vaiController_)) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n ensureNonzeroAddress(address(vaiController_));\n\n VAIControllerInterface oldVaiController = vaiController;\n vaiController = vaiController_;\n emit NewVAIController(oldVaiController, vaiController_);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the VAI mint rate\n * @param newVAIMintRate The new VAI mint rate to be set\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setVAIMintRate(\n uint256 newVAIMintRate\n ) external compareValue(vaiMintRate, newVAIMintRate) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n uint256 oldVAIMintRate = vaiMintRate;\n vaiMintRate = newVAIMintRate;\n emit NewVAIMintRate(oldVAIMintRate, newVAIMintRate);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the minted VAI amount of the `owner`\n * @param owner The address of the account to set\n * @param amount The amount of VAI to set to the account\n * @return The number of minted VAI by `owner`\n */\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256) {\n checkProtocolPauseState();\n\n // Pausing is a very serious situation - we revert to sound the alarms\n require(!mintVAIGuardianPaused && !repayVAIGuardianPaused, \"VAI is paused\");\n // Check caller is vaiController\n if (msg.sender != address(vaiController)) {\n return fail(Error.REJECTION, FailureInfo.SET_MINTED_VAI_REJECTION);\n }\n mintedVAIs[owner] = amount;\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the treasury data.\n * @param newTreasuryGuardian The new address of the treasury guardian to be set\n * @param newTreasuryAddress The new address of the treasury to be set\n * @param newTreasuryPercent The new treasury percent to be set\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setTreasuryData(\n address newTreasuryGuardian,\n address newTreasuryAddress,\n uint256 newTreasuryPercent\n ) external returns (uint256) {\n // Check caller is admin\n ensureAdminOr(treasuryGuardian);\n\n require(newTreasuryPercent < 1e18, \"percent >= 100%\");\n ensureNonzeroAddress(newTreasuryGuardian);\n ensureNonzeroAddress(newTreasuryAddress);\n\n address oldTreasuryGuardian = treasuryGuardian;\n address oldTreasuryAddress = treasuryAddress;\n uint256 oldTreasuryPercent = treasuryPercent;\n\n treasuryGuardian = newTreasuryGuardian;\n treasuryAddress = newTreasuryAddress;\n treasuryPercent = newTreasuryPercent;\n\n emit NewTreasuryGuardian(oldTreasuryGuardian, newTreasuryGuardian);\n emit NewTreasuryAddress(oldTreasuryAddress, newTreasuryAddress);\n emit NewTreasuryPercent(oldTreasuryPercent, newTreasuryPercent);\n\n return uint256(Error.NO_ERROR);\n }\n\n /*** Venus Distribution ***/\n\n /**\n * @dev Set ComptrollerLens contract address\n * @param comptrollerLens_ The new ComptrollerLens contract address to be set\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setComptrollerLens(\n ComptrollerLensInterface comptrollerLens_\n ) external compareAddress(address(comptrollerLens), address(comptrollerLens_)) returns (uint256) {\n ensureAdmin();\n ensureNonzeroAddress(address(comptrollerLens_));\n address oldComptrollerLens = address(comptrollerLens);\n comptrollerLens = comptrollerLens_;\n emit NewComptrollerLens(oldComptrollerLens, address(comptrollerLens));\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the amount of XVS distributed per block to VAI Vault\n * @param venusVAIVaultRate_ The amount of XVS wei per block to distribute to VAI Vault\n */\n function _setVenusVAIVaultRate(\n uint256 venusVAIVaultRate_\n ) external compareValue(venusVAIVaultRate, venusVAIVaultRate_) {\n ensureAdmin();\n if (vaiVaultAddress != address(0)) {\n releaseToVault();\n }\n uint256 oldVenusVAIVaultRate = venusVAIVaultRate;\n venusVAIVaultRate = venusVAIVaultRate_;\n emit NewVenusVAIVaultRate(oldVenusVAIVaultRate, venusVAIVaultRate_);\n }\n\n /**\n * @notice Set the VAI Vault infos\n * @param vault_ The address of the VAI Vault\n * @param releaseStartBlock_ The start block of release to VAI Vault\n * @param minReleaseAmount_ The minimum release amount to VAI Vault\n */\n function _setVAIVaultInfo(\n address vault_,\n uint256 releaseStartBlock_,\n uint256 minReleaseAmount_\n ) external compareAddress(vaiVaultAddress, vault_) {\n ensureAdmin();\n ensureNonzeroAddress(vault_);\n if (vaiVaultAddress != address(0)) {\n releaseToVault();\n }\n\n vaiVaultAddress = vault_;\n releaseStartBlock = releaseStartBlock_;\n minReleaseAmount = minReleaseAmount_;\n emit NewVAIVaultInfo(vault_, releaseStartBlock_, minReleaseAmount_);\n }\n\n /**\n * @notice Sets the prime token contract for the comptroller\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPrimeToken(IPrime _prime) external returns (uint) {\n ensureAdmin();\n ensureNonzeroAddress(address(_prime));\n\n IPrime oldPrime = prime;\n prime = _prime;\n emit NewPrimeToken(oldPrime, _prime);\n\n return uint(Error.NO_ERROR);\n }\n\n /** @notice Enables forced liquidations for a market. If forced liquidation is enabled,\n * borrows in the market may be liquidated regardless of the account liquidity\n * @dev Allows a privileged role to set enable/disable forced liquidations\n * @param vTokenBorrowed Borrowed vToken\n * @param enable Whether to enable forced liquidations\n */\n function _setForcedLiquidation(address vTokenBorrowed, bool enable) external {\n ensureAllowed(\"_setForcedLiquidation(address,bool)\");\n if (vTokenBorrowed != address(vaiController)) {\n ensureListed(markets[vTokenBorrowed]);\n }\n isForcedLiquidationEnabled[vTokenBorrowed] = enable;\n emit IsForcedLiquidationEnabledUpdated(vTokenBorrowed, enable);\n }\n\n /**\n * @notice Enables forced liquidations for user's borrows in a certain market. If forced\n * liquidation is enabled, user's borrows in the market may be liquidated regardless of\n * the account liquidity. Forced liquidation may be enabled for a user even if it is not\n * enabled for the entire market.\n * @param borrower The address of the borrower\n * @param vTokenBorrowed Borrowed vToken\n * @param enable Whether to enable forced liquidations\n */\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external {\n ensureAllowed(\"_setForcedLiquidationForUser(address,address,bool)\");\n if (vTokenBorrowed != address(vaiController)) {\n ensureListed(markets[vTokenBorrowed]);\n }\n isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed] = enable;\n emit IsForcedLiquidationEnabledForUserUpdated(borrower, vTokenBorrowed, enable);\n }\n\n /**\n * @notice Set the address of the XVS token\n * @param xvs_ The address of the XVS token\n */\n function _setXVSToken(address xvs_) external {\n ensureAdmin();\n ensureNonzeroAddress(xvs_);\n\n emit NewXVSToken(xvs, xvs_);\n xvs = xvs_;\n }\n\n /**\n * @notice Set the address of the XVS vToken\n * @param xvsVToken_ The address of the XVS vToken\n */\n function _setXVSVToken(address xvsVToken_) external {\n ensureAdmin();\n ensureNonzeroAddress(xvsVToken_);\n\n address underlying = VToken(xvsVToken_).underlying();\n require(underlying == xvs, \"invalid xvs vtoken address\");\n\n emit NewXVSVToken(xvsVToken, xvsVToken_);\n xvsVToken = xvsVToken_;\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { FacetBase } from \"./FacetBase.sol\";\n\n/**\n * @title XVSRewardsHelper\n * @author Venus\n * @dev This contract contains internal functions used in RewardFacet and PolicyFacet\n * @notice This facet contract contains the shared functions used by the RewardFacet and PolicyFacet\n */\ncontract XVSRewardsHelper is FacetBase {\n /// @notice Emitted when XVS is distributed to a borrower\n event DistributedBorrowerVenus(\n VToken indexed vToken,\n address indexed borrower,\n uint256 venusDelta,\n uint256 venusBorrowIndex\n );\n\n /// @notice Emitted when XVS is distributed to a supplier\n event DistributedSupplierVenus(\n VToken indexed vToken,\n address indexed supplier,\n uint256 venusDelta,\n uint256 venusSupplyIndex\n );\n\n /**\n * @notice Accrue XVS to the market by updating the borrow index\n * @param vToken The market whose borrow index to update\n */\n function updateVenusBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\n VenusMarketState storage borrowState = venusBorrowState[vToken];\n uint256 borrowSpeed = venusBorrowSpeeds[vToken];\n uint32 blockNumber = getBlockNumberAsUint32();\n uint256 deltaBlocks = sub_(blockNumber, borrowState.block);\n if (deltaBlocks != 0 && borrowSpeed != 0) {\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint256 accruedVenus = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount != 0 ? fraction(accruedVenus, borrowAmount) : Double({ mantissa: 0 });\n borrowState.index = safe224(add_(Double({ mantissa: borrowState.index }), ratio).mantissa, \"224\");\n borrowState.block = blockNumber;\n } else if (deltaBlocks != 0) {\n borrowState.block = blockNumber;\n }\n }\n\n /**\n * @notice Accrue XVS to the market by updating the supply index\n * @param vToken The market whose supply index to update\n */\n function updateVenusSupplyIndex(address vToken) internal {\n VenusMarketState storage supplyState = venusSupplyState[vToken];\n uint256 supplySpeed = venusSupplySpeeds[vToken];\n uint32 blockNumber = getBlockNumberAsUint32();\n\n uint256 deltaBlocks = sub_(blockNumber, supplyState.block);\n if (deltaBlocks != 0 && supplySpeed != 0) {\n uint256 supplyTokens = VToken(vToken).totalSupply();\n uint256 accruedVenus = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens != 0 ? fraction(accruedVenus, supplyTokens) : Double({ mantissa: 0 });\n supplyState.index = safe224(add_(Double({ mantissa: supplyState.index }), ratio).mantissa, \"224\");\n supplyState.block = blockNumber;\n } else if (deltaBlocks != 0) {\n supplyState.block = blockNumber;\n }\n }\n\n /**\n * @notice Calculate XVS accrued by a supplier and possibly transfer it to them\n * @param vToken The market in which the supplier is interacting\n * @param supplier The address of the supplier to distribute XVS to\n */\n function distributeSupplierVenus(address vToken, address supplier) internal {\n if (address(vaiVaultAddress) != address(0)) {\n releaseToVault();\n }\n uint256 supplyIndex = venusSupplyState[vToken].index;\n uint256 supplierIndex = venusSupplierIndex[vToken][supplier];\n // Update supplier's index to the current index since we are distributing accrued XVS\n venusSupplierIndex[vToken][supplier] = supplyIndex;\n if (supplierIndex == 0 && supplyIndex >= venusInitialIndex) {\n // Covers the case where users supplied tokens before the market's supply state index was set.\n // Rewards the user with XVS accrued from the start of when supplier rewards were first\n // set for the market.\n supplierIndex = venusInitialIndex;\n }\n // Calculate change in the cumulative sum of the XVS per vToken accrued\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\n // Multiply of supplierTokens and supplierDelta\n uint256 supplierDelta = mul_(VToken(vToken).balanceOf(supplier), deltaIndex);\n // Addition of supplierAccrued and supplierDelta\n venusAccrued[supplier] = add_(venusAccrued[supplier], supplierDelta);\n emit DistributedSupplierVenus(VToken(vToken), supplier, supplierDelta, supplyIndex);\n }\n\n /**\n * @notice Calculate XVS accrued by a borrower and possibly transfer it to them\n * @dev Borrowers will not begin to accrue until after the first interaction with the protocol\n * @param vToken The market in which the borrower is interacting\n * @param borrower The address of the borrower to distribute XVS to\n */\n function distributeBorrowerVenus(address vToken, address borrower, Exp memory marketBorrowIndex) internal {\n if (address(vaiVaultAddress) != address(0)) {\n releaseToVault();\n }\n uint256 borrowIndex = venusBorrowState[vToken].index;\n uint256 borrowerIndex = venusBorrowerIndex[vToken][borrower];\n // Update borrowers's index to the current index since we are distributing accrued XVS\n venusBorrowerIndex[vToken][borrower] = borrowIndex;\n if (borrowerIndex == 0 && borrowIndex >= venusInitialIndex) {\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\n // Rewards the user with XVS accrued from the start of when borrower rewards were first\n // set for the market.\n borrowerIndex = venusInitialIndex;\n }\n // Calculate change in the cumulative sum of the XVS per borrowed unit accrued\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\n uint256 borrowerDelta = mul_(div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex);\n venusAccrued[borrower] = add_(venusAccrued[borrower], borrowerDelta);\n emit DistributedBorrowerVenus(VToken(vToken), borrower, borrowerDelta, borrowIndex);\n }\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\npragma experimental ABIEncoderV2;\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n function diamondCut(FacetCut[] calldata _diamondCut) external;\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\n\ninterface IMarketFacet {\n function isComptroller() external pure returns (bool);\n\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view returns (uint256, uint256);\n\n function liquidateVAICalculateSeizeTokens(\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view returns (uint256, uint256);\n\n function checkMembership(address account, VToken vToken) external view returns (bool);\n\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\n\n function exitMarket(address vToken) external returns (uint256);\n\n function _supportMarket(VToken vToken) external returns (uint256);\n\n function getAssetsIn(address account) external view returns (VToken[] memory);\n\n function getAllMarkets() external view returns (VToken[] memory);\n\n function updateDelegate(address delegate, bool allowBorrows) external;\n\n function unlistMarket(address market) external returns (uint256);\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\n\ninterface IPolicyFacet {\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256);\n\n function mintVerify(address vToken, address minter, uint256 mintAmount, uint256 mintTokens) external;\n\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256);\n\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external;\n\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256);\n\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external;\n\n function repayBorrowAllowed(\n address vToken,\n address payer,\n address borrower,\n uint256 repayAmount\n ) external returns (uint256);\n\n function repayBorrowVerify(\n address vToken,\n address payer,\n address borrower,\n uint256 repayAmount,\n uint256 borrowerIndex\n ) external;\n\n function liquidateBorrowAllowed(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint256 repayAmount\n ) external view returns (uint256);\n\n function liquidateBorrowVerify(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint256 repayAmount,\n uint256 seizeTokens\n ) external;\n\n function seizeAllowed(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external returns (uint256);\n\n function seizeVerify(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external;\n\n function transferAllowed(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external returns (uint256);\n\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external;\n\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);\n\n function getHypotheticalAccountLiquidity(\n address account,\n address vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n ) external view returns (uint256, uint256, uint256);\n\n function _setVenusSpeeds(\n VToken[] calldata vTokens,\n uint256[] calldata supplySpeeds,\n uint256[] calldata borrowSpeeds\n ) external;\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { ComptrollerTypes } from \"../../ComptrollerStorage.sol\";\n\ninterface IRewardFacet {\n function claimVenus(address holder) external;\n\n function claimVenus(address holder, VToken[] calldata vTokens) external;\n\n function claimVenus(address[] calldata holders, VToken[] calldata vTokens, bool borrowers, bool suppliers) external;\n\n function claimVenusAsCollateral(address holder) external;\n\n function _grantXVS(address recipient, uint256 amount) external;\n\n function getXVSAddress() external view returns (address);\n\n function getXVSVTokenAddress() external view returns (address);\n\n function actionPaused(address market, ComptrollerTypes.Action action) external view returns (bool);\n\n function claimVenus(\n address[] calldata holders,\n VToken[] calldata vTokens,\n bool borrowers,\n bool suppliers,\n bool collateral\n ) external;\n function seizeVenus(address[] calldata holders, address recipient) external returns (uint256);\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { PriceOracle } from \"../../../Oracle/PriceOracle.sol\";\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { ComptrollerTypes } from \"../../ComptrollerStorage.sol\";\nimport { VAIControllerInterface } from \"../../../Tokens/VAI/VAIControllerInterface.sol\";\nimport { ComptrollerLensInterface } from \"../../../Comptroller/ComptrollerLensInterface.sol\";\nimport { IPrime } from \"../../../Tokens/Prime/IPrime.sol\";\n\ninterface ISetterFacet {\n function _setPriceOracle(PriceOracle newOracle) external returns (uint256);\n\n function _setCloseFactor(uint256 newCloseFactorMantissa) external returns (uint256);\n\n function _setAccessControl(address newAccessControlAddress) external returns (uint256);\n\n function _setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256);\n\n function _setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256);\n\n function _setLiquidatorContract(address newLiquidatorContract_) external;\n\n function _setPauseGuardian(address newPauseGuardian) external returns (uint256);\n\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external;\n\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external;\n\n function _setProtocolPaused(bool state) external returns (bool);\n\n function _setActionsPaused(\n address[] calldata markets,\n ComptrollerTypes.Action[] calldata actions,\n bool paused\n ) external;\n\n function _setVAIController(VAIControllerInterface vaiController_) external returns (uint256);\n\n function _setVAIMintRate(uint256 newVAIMintRate) external returns (uint256);\n\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256);\n\n function _setTreasuryData(\n address newTreasuryGuardian,\n address newTreasuryAddress,\n uint256 newTreasuryPercent\n ) external returns (uint256);\n\n function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint256);\n\n function _setVenusVAIVaultRate(uint256 venusVAIVaultRate_) external;\n\n function _setVAIVaultInfo(address vault_, uint256 releaseStartBlock_, uint256 minReleaseAmount_) external;\n\n function _setForcedLiquidation(address vToken, bool enable) external;\n\n function _setPrimeToken(IPrime _prime) external returns (uint);\n\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external;\n\n function _setXVSToken(address xvs_) external;\n\n function _setXVSVToken(address xvsVToken_) external;\n}\n" + }, + "contracts/Comptroller/Unitroller.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./ComptrollerStorage.sol\";\nimport \"../Utils/ErrorReporter.sol\";\n\n/**\n * @title ComptrollerCore\n * @dev Storage for the comptroller is at this address, while execution is delegated to the `comptrollerImplementation`.\n * VTokens should reference this contract as their comptroller.\n */\ncontract Unitroller is UnitrollerAdminStorage, ComptrollerErrorReporter {\n /**\n * @notice Emitted when pendingComptrollerImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingComptrollerImplementation is accepted, which means comptroller implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor() public {\n // Set admin to caller\n admin = msg.sender;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public returns (uint) {\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK);\n }\n\n address oldPendingImplementation = pendingComptrollerImplementation;\n\n pendingComptrollerImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingComptrollerImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts new implementation of comptroller. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public returns (uint) {\n // Check caller is pendingImplementation and pendingImplementation ≠ address(0)\n if (msg.sender != pendingComptrollerImplementation || pendingComptrollerImplementation == address(0)) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldImplementation = comptrollerImplementation;\n address oldPendingImplementation = pendingComptrollerImplementation;\n\n comptrollerImplementation = pendingComptrollerImplementation;\n\n pendingComptrollerImplementation = address(0);\n\n emit NewImplementation(oldImplementation, comptrollerImplementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingComptrollerImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public returns (uint) {\n // Check caller = admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK);\n }\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public returns (uint) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = comptrollerImplementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/Governance/VTreasury.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/IBEP20.sol\";\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/Ownable.sol\";\n\n/**\n * @title VTreasury\n * @author Venus\n * @notice Protocol treasury that holds tokens owned by Venus\n */\ncontract VTreasury is Ownable {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n // WithdrawTreasuryBEP20 Event\n event WithdrawTreasuryBEP20(address tokenAddress, uint256 withdrawAmount, address withdrawAddress);\n\n // WithdrawTreasuryBNB Event\n event WithdrawTreasuryBNB(uint256 withdrawAmount, address withdrawAddress);\n\n /**\n * @notice To receive BNB\n */\n function() external payable {}\n\n /**\n * @notice Withdraw Treasury BEP20 Tokens, Only owner call it\n * @param tokenAddress The address of treasury token\n * @param withdrawAmount The withdraw amount to owner\n * @param withdrawAddress The withdraw address\n */\n function withdrawTreasuryBEP20(\n address tokenAddress,\n uint256 withdrawAmount,\n address withdrawAddress\n ) external onlyOwner {\n uint256 actualWithdrawAmount = withdrawAmount;\n // Get Treasury Token Balance\n uint256 treasuryBalance = IBEP20(tokenAddress).balanceOf(address(this));\n\n // Check Withdraw Amount\n if (withdrawAmount > treasuryBalance) {\n // Update actualWithdrawAmount\n actualWithdrawAmount = treasuryBalance;\n }\n\n // Transfer BEP20 Token to withdrawAddress\n IBEP20(tokenAddress).safeTransfer(withdrawAddress, actualWithdrawAmount);\n\n emit WithdrawTreasuryBEP20(tokenAddress, actualWithdrawAmount, withdrawAddress);\n }\n\n /**\n * @notice Withdraw Treasury BNB, Only owner call it\n * @param withdrawAmount The withdraw amount to owner\n * @param withdrawAddress The withdraw address\n */\n function withdrawTreasuryBNB(uint256 withdrawAmount, address payable withdrawAddress) external payable onlyOwner {\n uint256 actualWithdrawAmount = withdrawAmount;\n // Get Treasury BNB Balance\n uint256 bnbBalance = address(this).balance;\n\n // Check Withdraw Amount\n if (withdrawAmount > bnbBalance) {\n // Update actualWithdrawAmount\n actualWithdrawAmount = bnbBalance;\n }\n // Transfer BNB to withdrawAddress\n withdrawAddress.transfer(actualWithdrawAmount);\n\n emit WithdrawTreasuryBNB(actualWithdrawAmount, withdrawAddress);\n }\n}\n" + }, + "contracts/InterestRateModels/InterestRateModel.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title Venus's InterestRateModel Interface\n * @author Venus\n */\ncontract InterestRateModel {\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\n bool public constant isInterestRateModel = true;\n\n /**\n * @notice Calculates the current borrow interest rate per block\n * @param cash The total amount of cash the market has\n * @param borrows The total amount of borrows the market has outstanding\n * @param reserves The total amnount of reserves the market has\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\n */\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\n\n /**\n * @notice Calculates the current supply interest rate per block\n * @param cash The total amount of cash the market has\n * @param borrows The total amount of borrows the market has outstanding\n * @param reserves The total amnount of reserves the market has\n * @param reserveFactorMantissa The current reserve factor the market has\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\n */\n function getSupplyRate(\n uint cash,\n uint borrows,\n uint reserves,\n uint reserveFactorMantissa\n ) external view returns (uint);\n}\n" + }, + "contracts/InterestRateModels/JumpRateModel.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\nimport \"./InterestRateModel.sol\";\n\n/**\n * @title Venus's JumpRateModel Contract\n * @author Venus\n */\ncontract JumpRateModel is InterestRateModel {\n using SafeMath for uint;\n\n event NewInterestParams(uint baseRatePerBlock, uint multiplierPerBlock, uint jumpMultiplierPerBlock, uint kink);\n\n /**\n * @notice The approximate number of blocks per year that is assumed by the interest rate model\n */\n uint public constant blocksPerYear = (60 * 60 * 24 * 365) / 3; // (assuming 3s blocks)\n\n /**\n * @notice The multiplier of utilization rate that gives the slope of the interest rate\n */\n uint public multiplierPerBlock;\n\n /**\n * @notice The base interest rate which is the y-intercept when utilization rate is 0\n */\n uint public baseRatePerBlock;\n\n /**\n * @notice The multiplierPerBlock after hitting a specified utilization point\n */\n uint public jumpMultiplierPerBlock;\n\n /**\n * @notice The utilization point at which the jump multiplier is applied\n */\n uint public kink;\n\n /**\n * @notice Construct an interest rate model\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by 1e18)\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by 1e18)\n * @param jumpMultiplierPerYear The multiplierPerBlock after hitting a specified utilization point\n * @param kink_ The utilization point at which the jump multiplier is applied\n */\n constructor(uint baseRatePerYear, uint multiplierPerYear, uint jumpMultiplierPerYear, uint kink_) public {\n baseRatePerBlock = baseRatePerYear.div(blocksPerYear);\n multiplierPerBlock = multiplierPerYear.div(blocksPerYear);\n jumpMultiplierPerBlock = jumpMultiplierPerYear.div(blocksPerYear);\n kink = kink_;\n\n emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink);\n }\n\n /**\n * @notice Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market (currently unused)\n * @return The utilization rate as a mantissa between [0, 1e18]\n */\n function utilizationRate(uint cash, uint borrows, uint reserves) public pure returns (uint) {\n // Utilization rate is 0 when there are no borrows\n if (borrows == 0) {\n return 0;\n }\n\n return borrows.mul(1e18).div(cash.add(borrows).sub(reserves));\n }\n\n /**\n * @notice Calculates the current borrow rate per block, with the error code expected by the market\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market\n * @return The borrow rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getBorrowRate(uint cash, uint borrows, uint reserves) public view returns (uint) {\n uint util = utilizationRate(cash, borrows, reserves);\n\n if (util <= kink) {\n return util.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);\n } else {\n uint normalRate = kink.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);\n uint excessUtil = util.sub(kink);\n return excessUtil.mul(jumpMultiplierPerBlock).div(1e18).add(normalRate);\n }\n }\n\n /**\n * @notice Calculates the current supply rate per block\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market\n * @param reserveFactorMantissa The current reserve factor for the market\n * @return The supply rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getSupplyRate(\n uint cash,\n uint borrows,\n uint reserves,\n uint reserveFactorMantissa\n ) public view returns (uint) {\n uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa);\n uint borrowRate = getBorrowRate(cash, borrows, reserves);\n uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18);\n return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18);\n }\n}\n" + }, + "contracts/InterestRateModels/WhitePaperInterestRateModel.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\nimport \"./InterestRateModel.sol\";\n\n/**\n * @title Venus's WhitePaperInterestRateModel Contract\n * @author Venus\n * @notice The parameterized model described in section 2.4 of the original Venus Protocol whitepaper\n */\ncontract WhitePaperInterestRateModel is InterestRateModel {\n using SafeMath for uint;\n\n event NewInterestParams(uint baseRatePerBlock, uint multiplierPerBlock);\n\n /**\n * @notice The approximate number of blocks per year that is assumed by the interest rate model\n */\n uint public constant blocksPerYear = (60 * 60 * 24 * 365) / 3; // (assuming 3s blocks)\n\n /**\n * @notice The multiplier of utilization rate that gives the slope of the interest rate\n */\n uint public multiplierPerBlock;\n\n /**\n * @notice The base interest rate which is the y-intercept when utilization rate is 0\n */\n uint public baseRatePerBlock;\n\n /**\n * @notice Construct an interest rate model\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by 1e18)\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by 1e18)\n */\n constructor(uint baseRatePerYear, uint multiplierPerYear) public {\n baseRatePerBlock = baseRatePerYear.div(blocksPerYear);\n multiplierPerBlock = multiplierPerYear.div(blocksPerYear);\n\n emit NewInterestParams(baseRatePerBlock, multiplierPerBlock);\n }\n\n /**\n * @notice Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market (currently unused)\n * @return The utilization rate as a mantissa between [0, 1e18]\n */\n function utilizationRate(uint cash, uint borrows, uint reserves) public pure returns (uint) {\n // Utilization rate is 0 when there are no borrows\n if (borrows == 0) {\n return 0;\n }\n\n return borrows.mul(1e18).div(cash.add(borrows).sub(reserves));\n }\n\n /**\n * @notice Calculates the current borrow rate per block, with the error code expected by the market\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market\n * @return The borrow rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getBorrowRate(uint cash, uint borrows, uint reserves) public view returns (uint) {\n uint ur = utilizationRate(cash, borrows, reserves);\n return ur.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);\n }\n\n /**\n * @notice Calculates the current supply rate per block\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market\n * @param reserveFactorMantissa The current reserve factor for the market\n * @return The supply rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getSupplyRate(\n uint cash,\n uint borrows,\n uint reserves,\n uint reserveFactorMantissa\n ) public view returns (uint) {\n uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa);\n uint borrowRate = getBorrowRate(cash, borrows, reserves);\n uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18);\n return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18);\n }\n}\n" + }, + "contracts/Lens/ComptrollerLens.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Tokens/VTokens/VBep20.sol\";\nimport { VToken } from \"../Tokens/VTokens/VToken.sol\";\nimport { ExponentialNoError } from \"../Utils/ExponentialNoError.sol\";\nimport \"../Tokens/EIP20Interface.sol\";\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Utils/ErrorReporter.sol\";\nimport \"../Comptroller/ComptrollerInterface.sol\";\nimport \"../Comptroller/ComptrollerLensInterface.sol\";\nimport \"../Tokens/VAI/VAIControllerInterface.sol\";\n\n/**\n * @title ComptrollerLens Contract\n * @author Venus\n * @notice The ComptrollerLens contract has functions to get the number of tokens that\n * can be seized through liquidation, hypothetical account liquidity and shortfall of an account.\n */\ncontract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, ExponentialNoError {\n /**\n * @dev Local vars for avoiding stack-depth limits in calculating account liquidity.\n * Note that `vTokenBalance` is the number of vTokens the account owns in the market,\n * whereas `borrowBalance` is the amount of underlying that the account has borrowed.\n */\n struct AccountLiquidityLocalVars {\n uint sumCollateral;\n uint sumBorrowPlusEffects;\n uint vTokenBalance;\n uint borrowBalance;\n uint exchangeRateMantissa;\n uint oraclePriceMantissa;\n Exp collateralFactor;\n Exp exchangeRate;\n Exp oraclePrice;\n Exp tokensToDenom;\n }\n\n /**\n * @notice Computes the number of collateral tokens to be seized in a liquidation event\n * @param comptroller Address of comptroller\n * @param vTokenBorrowed Address of the borrowed vToken\n * @param vTokenCollateral Address of collateral for the borrow\n * @param actualRepayAmount Repayment amount i.e amount to be repaid of total borrowed amount\n * @return A tuple of error code, and tokens to seize\n */\n function liquidateCalculateSeizeTokens(\n address comptroller,\n address vTokenBorrowed,\n address vTokenCollateral,\n uint actualRepayAmount\n ) external view returns (uint, uint) {\n /* Read oracle prices for borrowed and collateral markets */\n uint priceBorrowedMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(\n VToken(vTokenBorrowed)\n );\n uint priceCollateralMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(\n VToken(vTokenCollateral)\n );\n if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) {\n return (uint(Error.PRICE_ERROR), 0);\n }\n\n /*\n * Get the exchange rate and calculate the number of collateral tokens to seize:\n * seizeAmount = actualRepayAmount * liquidationIncentive * priceBorrowed / priceCollateral\n * seizeTokens = seizeAmount / exchangeRate\n * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate)\n */\n uint exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\n uint seizeTokens;\n Exp memory numerator;\n Exp memory denominator;\n Exp memory ratio;\n\n numerator = mul_(\n Exp({ mantissa: ComptrollerInterface(comptroller).liquidationIncentiveMantissa() }),\n Exp({ mantissa: priceBorrowedMantissa })\n );\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\n ratio = div_(numerator, denominator);\n\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\n\n return (uint(Error.NO_ERROR), seizeTokens);\n }\n\n /**\n * @notice Computes the number of VAI tokens to be seized in a liquidation event\n * @param comptroller Address of comptroller\n * @param vTokenCollateral Address of collateral for vToken\n * @param actualRepayAmount Repayment amount i.e amount to be repaid of the total borrowed amount\n * @return A tuple of error code, and tokens to seize\n */\n function liquidateVAICalculateSeizeTokens(\n address comptroller,\n address vTokenCollateral,\n uint actualRepayAmount\n ) external view returns (uint, uint) {\n /* Read oracle prices for borrowed and collateral markets */\n uint priceBorrowedMantissa = 1e18; // Note: this is VAI\n uint priceCollateralMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(\n VToken(vTokenCollateral)\n );\n if (priceCollateralMantissa == 0) {\n return (uint(Error.PRICE_ERROR), 0);\n }\n\n /*\n * Get the exchange rate and calculate the number of collateral tokens to seize:\n * seizeAmount = actualRepayAmount * liquidationIncentive * priceBorrowed / priceCollateral\n * seizeTokens = seizeAmount / exchangeRate\n * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate)\n */\n uint exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\n uint seizeTokens;\n Exp memory numerator;\n Exp memory denominator;\n Exp memory ratio;\n\n numerator = mul_(\n Exp({ mantissa: ComptrollerInterface(comptroller).liquidationIncentiveMantissa() }),\n Exp({ mantissa: priceBorrowedMantissa })\n );\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\n ratio = div_(numerator, denominator);\n\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\n\n return (uint(Error.NO_ERROR), seizeTokens);\n }\n\n /**\n * @notice Computes the hypothetical liquidity and shortfall of an account given a hypothetical borrow\n * A snapshot of the account is taken and the total borrow amount of the account is calculated\n * @param comptroller Address of comptroller\n * @param account Address of the borrowed vToken\n * @param vTokenModify Address of collateral for vToken\n * @param redeemTokens Number of vTokens being redeemed\n * @param borrowAmount Amount borrowed\n * @return Returns a tuple of error code, liquidity, and shortfall\n */\n function getHypotheticalAccountLiquidity(\n address comptroller,\n address account,\n VToken vTokenModify,\n uint redeemTokens,\n uint borrowAmount\n ) external view returns (uint, uint, uint) {\n AccountLiquidityLocalVars memory vars; // Holds all our calculation results\n uint oErr;\n\n // For each asset the account is in\n VToken[] memory assets = ComptrollerInterface(comptroller).getAssetsIn(account);\n uint assetsCount = assets.length;\n for (uint i = 0; i < assetsCount; ++i) {\n VToken asset = assets[i];\n\n // Read the balances and exchange rate from the vToken\n (oErr, vars.vTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(\n account\n );\n if (oErr != 0) {\n // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades\n return (uint(Error.SNAPSHOT_ERROR), 0, 0);\n }\n (, uint collateralFactorMantissa) = ComptrollerInterface(comptroller).markets(address(asset));\n vars.collateralFactor = Exp({ mantissa: collateralFactorMantissa });\n vars.exchangeRate = Exp({ mantissa: vars.exchangeRateMantissa });\n\n // Get the normalized price of the asset\n vars.oraclePriceMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(asset);\n if (vars.oraclePriceMantissa == 0) {\n return (uint(Error.PRICE_ERROR), 0, 0);\n }\n vars.oraclePrice = Exp({ mantissa: vars.oraclePriceMantissa });\n\n // Pre-compute a conversion factor from tokens -> bnb (normalized price value)\n vars.tokensToDenom = mul_(mul_(vars.collateralFactor, vars.exchangeRate), vars.oraclePrice);\n\n // sumCollateral += tokensToDenom * vTokenBalance\n vars.sumCollateral = mul_ScalarTruncateAddUInt(vars.tokensToDenom, vars.vTokenBalance, vars.sumCollateral);\n\n // sumBorrowPlusEffects += oraclePrice * borrowBalance\n vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(\n vars.oraclePrice,\n vars.borrowBalance,\n vars.sumBorrowPlusEffects\n );\n\n // Calculate effects of interacting with vTokenModify\n if (asset == vTokenModify) {\n // redeem effect\n // sumBorrowPlusEffects += tokensToDenom * redeemTokens\n vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(\n vars.tokensToDenom,\n redeemTokens,\n vars.sumBorrowPlusEffects\n );\n\n // borrow effect\n // sumBorrowPlusEffects += oraclePrice * borrowAmount\n vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(\n vars.oraclePrice,\n borrowAmount,\n vars.sumBorrowPlusEffects\n );\n }\n }\n\n VAIControllerInterface vaiController = ComptrollerInterface(comptroller).vaiController();\n\n if (address(vaiController) != address(0)) {\n vars.sumBorrowPlusEffects = add_(vars.sumBorrowPlusEffects, vaiController.getVAIRepayAmount(account));\n }\n\n // These are safe, as the underflow condition is checked first\n if (vars.sumCollateral > vars.sumBorrowPlusEffects) {\n return (uint(Error.NO_ERROR), vars.sumCollateral - vars.sumBorrowPlusEffects, 0);\n } else {\n return (uint(Error.NO_ERROR), 0, vars.sumBorrowPlusEffects - vars.sumCollateral);\n }\n }\n}\n" + }, + "contracts/Lens/SnapshotLens.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport { VToken } from \"../Tokens/VTokens/VToken.sol\";\nimport { ExponentialNoError } from \"../Utils/ExponentialNoError.sol\";\nimport \"../Utils/SafeMath.sol\";\nimport \"../Comptroller/ComptrollerInterface.sol\";\nimport \"../Tokens/EIP20Interface.sol\";\nimport \"../Tokens/VTokens/VBep20.sol\";\n\ncontract SnapshotLens is ExponentialNoError {\n using SafeMath for uint256;\n\n struct AccountSnapshot {\n address account;\n string assetName;\n address vTokenAddress;\n address underlyingAssetAddress;\n uint256 supply;\n uint256 supplyInUsd;\n uint256 collateral;\n uint256 borrows;\n uint256 borrowsInUsd;\n uint256 assetPrice;\n uint256 accruedInterest;\n uint vTokenDecimals;\n uint underlyingDecimals;\n uint exchangeRate;\n bool isACollateral;\n }\n\n /** Snapshot calculation **/\n /**\n * @dev Local vars for avoiding stack-depth limits in calculating account snapshot.\n * Note that `vTokenBalance` is the number of vTokens the account owns in the market,\n * whereas `borrowBalance` is the amount of underlying that the account has borrowed.\n */\n struct AccountSnapshotLocalVars {\n uint collateral;\n uint vTokenBalance;\n uint borrowBalance;\n uint borrowsInUsd;\n uint balanceOfUnderlying;\n uint supplyInUsd;\n uint exchangeRateMantissa;\n uint oraclePriceMantissa;\n Exp collateralFactor;\n Exp exchangeRate;\n Exp oraclePrice;\n Exp tokensToDenom;\n bool isACollateral;\n }\n\n function getAccountSnapshot(\n address payable account,\n address comptrollerAddress\n ) public returns (AccountSnapshot[] memory) {\n // For each asset the account is in\n VToken[] memory assets = ComptrollerInterface(comptrollerAddress).getAllMarkets();\n AccountSnapshot[] memory accountSnapshots = new AccountSnapshot[](assets.length);\n for (uint256 i = 0; i < assets.length; ++i) {\n accountSnapshots[i] = getAccountSnapshot(account, comptrollerAddress, assets[i]);\n }\n return accountSnapshots;\n }\n\n function isACollateral(address account, address asset, address comptrollerAddress) public view returns (bool) {\n VToken[] memory assetsAsCollateral = ComptrollerInterface(comptrollerAddress).getAssetsIn(account);\n for (uint256 j = 0; j < assetsAsCollateral.length; ++j) {\n if (address(assetsAsCollateral[j]) == asset) {\n return true;\n }\n }\n\n return false;\n }\n\n function getAccountSnapshot(\n address payable account,\n address comptrollerAddress,\n VToken vToken\n ) public returns (AccountSnapshot memory) {\n AccountSnapshotLocalVars memory vars; // Holds all our calculation results\n uint oErr;\n\n // Read the balances and exchange rate from the vToken\n (oErr, vars.vTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = vToken.getAccountSnapshot(account);\n require(oErr == 0, \"Snapshot Error\");\n vars.exchangeRate = Exp({ mantissa: vars.exchangeRateMantissa });\n\n (, uint collateralFactorMantissa) = ComptrollerInterface(comptrollerAddress).markets(address(vToken));\n vars.collateralFactor = Exp({ mantissa: collateralFactorMantissa });\n\n // Get the normalized price of the asset\n vars.oraclePriceMantissa = ComptrollerInterface(comptrollerAddress).oracle().getUnderlyingPrice(vToken);\n vars.oraclePrice = Exp({ mantissa: vars.oraclePriceMantissa });\n\n // Pre-compute a conversion factor from tokens -> bnb (normalized price value)\n vars.tokensToDenom = mul_(mul_(vars.collateralFactor, vars.exchangeRate), vars.oraclePrice);\n\n //Collateral = tokensToDenom * vTokenBalance\n vars.collateral = mul_ScalarTruncate(vars.tokensToDenom, vars.vTokenBalance);\n\n vars.balanceOfUnderlying = vToken.balanceOfUnderlying(account);\n vars.supplyInUsd = mul_ScalarTruncate(vars.oraclePrice, vars.balanceOfUnderlying);\n\n vars.borrowsInUsd = mul_ScalarTruncate(vars.oraclePrice, vars.borrowBalance);\n\n address underlyingAssetAddress;\n uint underlyingDecimals;\n\n if (compareStrings(vToken.symbol(), \"vBNB\")) {\n underlyingAssetAddress = address(0);\n underlyingDecimals = 18;\n } else {\n VBep20 vBep20 = VBep20(address(vToken));\n underlyingAssetAddress = vBep20.underlying();\n underlyingDecimals = EIP20Interface(vBep20.underlying()).decimals();\n }\n\n vars.isACollateral = isACollateral(account, address(vToken), comptrollerAddress);\n\n return\n AccountSnapshot({\n account: account,\n assetName: vToken.name(),\n vTokenAddress: address(vToken),\n underlyingAssetAddress: underlyingAssetAddress,\n supply: vars.balanceOfUnderlying,\n supplyInUsd: vars.supplyInUsd,\n collateral: vars.collateral,\n borrows: vars.borrowBalance,\n borrowsInUsd: vars.borrowsInUsd,\n assetPrice: vars.oraclePriceMantissa,\n accruedInterest: vToken.borrowIndex(),\n vTokenDecimals: vToken.decimals(),\n underlyingDecimals: underlyingDecimals,\n exchangeRate: vToken.exchangeRateCurrent(),\n isACollateral: vars.isACollateral\n });\n }\n\n // utilities\n function compareStrings(string memory a, string memory b) internal pure returns (bool) {\n return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));\n }\n}\n" + }, + "contracts/Lens/VenusLens.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Tokens/VTokens/VBep20.sol\";\nimport \"../Tokens/VTokens/VToken.sol\";\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Tokens/EIP20Interface.sol\";\nimport \"../Tokens/XVS/XVS.sol\";\nimport \"../Comptroller/ComptrollerInterface.sol\";\nimport \"../Utils/SafeMath.sol\";\nimport { ComptrollerTypes } from \"../Comptroller/ComptrollerStorage.sol\";\n\ncontract VenusLens is ExponentialNoError {\n using SafeMath for uint;\n\n /// @notice Blocks Per Day\n uint public constant BLOCKS_PER_DAY = 28800;\n\n /// @notice Total actions available on VToken\n uint public constant VTOKEN_ACTIONS = 8;\n\n struct VenusMarketState {\n uint224 index;\n uint32 block;\n }\n\n struct VTokenMetadata {\n address vToken;\n uint exchangeRateCurrent;\n uint supplyRatePerBlock;\n uint borrowRatePerBlock;\n uint reserveFactorMantissa;\n uint totalBorrows;\n uint totalReserves;\n uint totalSupply;\n uint totalCash;\n bool isListed;\n uint collateralFactorMantissa;\n address underlyingAssetAddress;\n uint vTokenDecimals;\n uint underlyingDecimals;\n uint venusSupplySpeed;\n uint venusBorrowSpeed;\n uint dailySupplyXvs;\n uint dailyBorrowXvs;\n uint pausedActions;\n }\n\n struct VTokenBalances {\n address vToken;\n uint balanceOf;\n uint borrowBalanceCurrent;\n uint balanceOfUnderlying;\n uint tokenBalance;\n uint tokenAllowance;\n }\n\n struct VTokenUnderlyingPrice {\n address vToken;\n uint underlyingPrice;\n }\n\n struct AccountLimits {\n VToken[] markets;\n uint liquidity;\n uint shortfall;\n }\n\n struct XVSBalanceMetadata {\n uint balance;\n uint votes;\n address delegate;\n }\n\n struct XVSBalanceMetadataExt {\n uint balance;\n uint votes;\n address delegate;\n uint allocated;\n }\n\n struct VenusVotes {\n uint blockNumber;\n uint votes;\n }\n\n struct ClaimVenusLocalVariables {\n uint totalRewards;\n uint224 borrowIndex;\n uint32 borrowBlock;\n uint224 supplyIndex;\n uint32 supplyBlock;\n }\n\n /**\n * @dev Struct for Pending Rewards for per market\n */\n struct PendingReward {\n address vTokenAddress;\n uint256 amount;\n }\n\n /**\n * @dev Struct for Reward of a single reward token.\n */\n struct RewardSummary {\n address distributorAddress;\n address rewardTokenAddress;\n uint256 totalRewards;\n PendingReward[] pendingRewards;\n }\n\n /**\n * @notice Query the metadata of a vToken by its address\n * @param vToken The address of the vToken to fetch VTokenMetadata\n * @return VTokenMetadata struct with vToken supply and borrow information.\n */\n function vTokenMetadata(VToken vToken) public returns (VTokenMetadata memory) {\n uint exchangeRateCurrent = vToken.exchangeRateCurrent();\n address comptrollerAddress = address(vToken.comptroller());\n ComptrollerInterface comptroller = ComptrollerInterface(comptrollerAddress);\n (bool isListed, uint collateralFactorMantissa) = comptroller.markets(address(vToken));\n address underlyingAssetAddress;\n uint underlyingDecimals;\n\n if (compareStrings(vToken.symbol(), \"vBNB\")) {\n underlyingAssetAddress = address(0);\n underlyingDecimals = 18;\n } else {\n VBep20 vBep20 = VBep20(address(vToken));\n underlyingAssetAddress = vBep20.underlying();\n underlyingDecimals = EIP20Interface(vBep20.underlying()).decimals();\n }\n\n uint venusSupplySpeedPerBlock = comptroller.venusSupplySpeeds(address(vToken));\n uint venusBorrowSpeedPerBlock = comptroller.venusBorrowSpeeds(address(vToken));\n\n uint256 pausedActions;\n\n for (uint8 i; i <= VTOKEN_ACTIONS; ++i) {\n uint256 paused = comptroller.actionPaused(address(vToken), ComptrollerTypes.Action(i)) ? 1 : 0;\n pausedActions |= paused << i;\n }\n\n return\n VTokenMetadata({\n vToken: address(vToken),\n exchangeRateCurrent: exchangeRateCurrent,\n supplyRatePerBlock: vToken.supplyRatePerBlock(),\n borrowRatePerBlock: vToken.borrowRatePerBlock(),\n reserveFactorMantissa: vToken.reserveFactorMantissa(),\n totalBorrows: vToken.totalBorrows(),\n totalReserves: vToken.totalReserves(),\n totalSupply: vToken.totalSupply(),\n totalCash: vToken.getCash(),\n isListed: isListed,\n collateralFactorMantissa: collateralFactorMantissa,\n underlyingAssetAddress: underlyingAssetAddress,\n vTokenDecimals: vToken.decimals(),\n underlyingDecimals: underlyingDecimals,\n venusSupplySpeed: venusSupplySpeedPerBlock,\n venusBorrowSpeed: venusBorrowSpeedPerBlock,\n dailySupplyXvs: venusSupplySpeedPerBlock.mul(BLOCKS_PER_DAY),\n dailyBorrowXvs: venusBorrowSpeedPerBlock.mul(BLOCKS_PER_DAY),\n pausedActions: pausedActions\n });\n }\n\n /**\n * @notice Get VTokenMetadata for an array of vToken addresses\n * @param vTokens Array of vToken addresses to fetch VTokenMetadata\n * @return Array of structs with vToken supply and borrow information.\n */\n function vTokenMetadataAll(VToken[] calldata vTokens) external returns (VTokenMetadata[] memory) {\n uint vTokenCount = vTokens.length;\n VTokenMetadata[] memory res = new VTokenMetadata[](vTokenCount);\n for (uint i = 0; i < vTokenCount; i++) {\n res[i] = vTokenMetadata(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Get amount of XVS distributed daily to an account\n * @param account Address of account to fetch the daily XVS distribution\n * @param comptrollerAddress Address of the comptroller proxy\n * @return Amount of XVS distributed daily to an account\n */\n function getDailyXVS(address payable account, address comptrollerAddress) external returns (uint) {\n ComptrollerInterface comptrollerInstance = ComptrollerInterface(comptrollerAddress);\n VToken[] memory vTokens = comptrollerInstance.getAllMarkets();\n uint dailyXvsPerAccount = 0;\n\n for (uint i = 0; i < vTokens.length; i++) {\n VToken vToken = vTokens[i];\n if (!compareStrings(vToken.symbol(), \"vUST\") && !compareStrings(vToken.symbol(), \"vLUNA\")) {\n VTokenMetadata memory metaDataItem = vTokenMetadata(vToken);\n\n //get balanceOfUnderlying and borrowBalanceCurrent from vTokenBalance\n VTokenBalances memory vTokenBalanceInfo = vTokenBalances(vToken, account);\n\n VTokenUnderlyingPrice memory underlyingPriceResponse = vTokenUnderlyingPrice(vToken);\n uint underlyingPrice = underlyingPriceResponse.underlyingPrice;\n Exp memory underlyingPriceMantissa = Exp({ mantissa: underlyingPrice });\n\n //get dailyXvsSupplyMarket\n uint dailyXvsSupplyMarket = 0;\n uint supplyInUsd = mul_ScalarTruncate(underlyingPriceMantissa, vTokenBalanceInfo.balanceOfUnderlying);\n uint marketTotalSupply = (metaDataItem.totalSupply.mul(metaDataItem.exchangeRateCurrent)).div(1e18);\n uint marketTotalSupplyInUsd = mul_ScalarTruncate(underlyingPriceMantissa, marketTotalSupply);\n\n if (marketTotalSupplyInUsd > 0) {\n dailyXvsSupplyMarket = (metaDataItem.dailySupplyXvs.mul(supplyInUsd)).div(marketTotalSupplyInUsd);\n }\n\n //get dailyXvsBorrowMarket\n uint dailyXvsBorrowMarket = 0;\n uint borrowsInUsd = mul_ScalarTruncate(underlyingPriceMantissa, vTokenBalanceInfo.borrowBalanceCurrent);\n uint marketTotalBorrowsInUsd = mul_ScalarTruncate(underlyingPriceMantissa, metaDataItem.totalBorrows);\n\n if (marketTotalBorrowsInUsd > 0) {\n dailyXvsBorrowMarket = (metaDataItem.dailyBorrowXvs.mul(borrowsInUsd)).div(marketTotalBorrowsInUsd);\n }\n\n dailyXvsPerAccount += dailyXvsSupplyMarket + dailyXvsBorrowMarket;\n }\n }\n\n return dailyXvsPerAccount;\n }\n\n /**\n * @notice Get the current vToken balance (outstanding borrows) for an account\n * @param vToken Address of the token to check the balance of\n * @param account Account address to fetch the balance of\n * @return VTokenBalances with token balance information\n */\n function vTokenBalances(VToken vToken, address payable account) public returns (VTokenBalances memory) {\n uint balanceOf = vToken.balanceOf(account);\n uint borrowBalanceCurrent = vToken.borrowBalanceCurrent(account);\n uint balanceOfUnderlying = vToken.balanceOfUnderlying(account);\n uint tokenBalance;\n uint tokenAllowance;\n\n if (compareStrings(vToken.symbol(), \"vBNB\")) {\n tokenBalance = account.balance;\n tokenAllowance = account.balance;\n } else {\n VBep20 vBep20 = VBep20(address(vToken));\n EIP20Interface underlying = EIP20Interface(vBep20.underlying());\n tokenBalance = underlying.balanceOf(account);\n tokenAllowance = underlying.allowance(account, address(vToken));\n }\n\n return\n VTokenBalances({\n vToken: address(vToken),\n balanceOf: balanceOf,\n borrowBalanceCurrent: borrowBalanceCurrent,\n balanceOfUnderlying: balanceOfUnderlying,\n tokenBalance: tokenBalance,\n tokenAllowance: tokenAllowance\n });\n }\n\n /**\n * @notice Get the current vToken balances (outstanding borrows) for all vTokens on an account\n * @param vTokens Addresses of the tokens to check the balance of\n * @param account Account address to fetch the balance of\n * @return VTokenBalances Array with token balance information\n */\n function vTokenBalancesAll(\n VToken[] calldata vTokens,\n address payable account\n ) external returns (VTokenBalances[] memory) {\n uint vTokenCount = vTokens.length;\n VTokenBalances[] memory res = new VTokenBalances[](vTokenCount);\n for (uint i = 0; i < vTokenCount; i++) {\n res[i] = vTokenBalances(vTokens[i], account);\n }\n return res;\n }\n\n /**\n * @notice Get the price for the underlying asset of a vToken\n * @param vToken address of the vToken\n * @return response struct with underlyingPrice info of vToken\n */\n function vTokenUnderlyingPrice(VToken vToken) public view returns (VTokenUnderlyingPrice memory) {\n ComptrollerInterface comptroller = ComptrollerInterface(address(vToken.comptroller()));\n PriceOracle priceOracle = comptroller.oracle();\n\n return\n VTokenUnderlyingPrice({ vToken: address(vToken), underlyingPrice: priceOracle.getUnderlyingPrice(vToken) });\n }\n\n /**\n * @notice Query the underlyingPrice of an array of vTokens\n * @param vTokens Array of vToken addresses\n * @return array of response structs with underlying price information of vTokens\n */\n function vTokenUnderlyingPriceAll(\n VToken[] calldata vTokens\n ) external view returns (VTokenUnderlyingPrice[] memory) {\n uint vTokenCount = vTokens.length;\n VTokenUnderlyingPrice[] memory res = new VTokenUnderlyingPrice[](vTokenCount);\n for (uint i = 0; i < vTokenCount; i++) {\n res[i] = vTokenUnderlyingPrice(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Query the account liquidity and shortfall of an account\n * @param comptroller Address of comptroller proxy\n * @param account Address of the account to query\n * @return Struct with markets user has entered, liquidity, and shortfall of the account\n */\n function getAccountLimits(\n ComptrollerInterface comptroller,\n address account\n ) public view returns (AccountLimits memory) {\n (uint errorCode, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(account);\n require(errorCode == 0, \"account liquidity error\");\n\n return AccountLimits({ markets: comptroller.getAssetsIn(account), liquidity: liquidity, shortfall: shortfall });\n }\n\n /**\n * @notice Query the XVSBalance info of an account\n * @param xvs XVS contract address\n * @param account Account address\n * @return Struct with XVS balance and voter details\n */\n function getXVSBalanceMetadata(XVS xvs, address account) external view returns (XVSBalanceMetadata memory) {\n return\n XVSBalanceMetadata({\n balance: xvs.balanceOf(account),\n votes: uint256(xvs.getCurrentVotes(account)),\n delegate: xvs.delegates(account)\n });\n }\n\n /**\n * @notice Query the XVSBalance extended info of an account\n * @param xvs XVS contract address\n * @param comptroller Comptroller proxy contract address\n * @param account Account address\n * @return Struct with XVS balance and voter details and XVS allocation\n */\n function getXVSBalanceMetadataExt(\n XVS xvs,\n ComptrollerInterface comptroller,\n address account\n ) external returns (XVSBalanceMetadataExt memory) {\n uint balance = xvs.balanceOf(account);\n comptroller.claimVenus(account);\n uint newBalance = xvs.balanceOf(account);\n uint accrued = comptroller.venusAccrued(account);\n uint total = add_(accrued, newBalance, \"sum xvs total\");\n uint allocated = sub_(total, balance, \"sub allocated\");\n\n return\n XVSBalanceMetadataExt({\n balance: balance,\n votes: uint256(xvs.getCurrentVotes(account)),\n delegate: xvs.delegates(account),\n allocated: allocated\n });\n }\n\n /**\n * @notice Query the voting power for an account at a specific list of block numbers\n * @param xvs XVS contract address\n * @param account Address of the account\n * @param blockNumbers Array of blocks to query\n * @return Array of VenusVotes structs with block number and vote count\n */\n function getVenusVotes(\n XVS xvs,\n address account,\n uint32[] calldata blockNumbers\n ) external view returns (VenusVotes[] memory) {\n VenusVotes[] memory res = new VenusVotes[](blockNumbers.length);\n for (uint i = 0; i < blockNumbers.length; i++) {\n res[i] = VenusVotes({\n blockNumber: uint256(blockNumbers[i]),\n votes: uint256(xvs.getPriorVotes(account, blockNumbers[i]))\n });\n }\n return res;\n }\n\n /**\n * @dev Queries the current supply to calculate rewards for an account\n * @param supplyState VenusMarketState struct\n * @param vToken Address of a vToken\n * @param comptroller Address of the comptroller proxy\n */\n function updateVenusSupplyIndex(\n VenusMarketState memory supplyState,\n address vToken,\n ComptrollerInterface comptroller\n ) internal view {\n uint supplySpeed = comptroller.venusSupplySpeeds(vToken);\n uint blockNumber = block.number;\n uint deltaBlocks = sub_(blockNumber, uint(supplyState.block));\n if (deltaBlocks > 0 && supplySpeed > 0) {\n uint supplyTokens = VToken(vToken).totalSupply();\n uint venusAccrued = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens > 0 ? fraction(venusAccrued, supplyTokens) : Double({ mantissa: 0 });\n Double memory index = add_(Double({ mantissa: supplyState.index }), ratio);\n supplyState.index = safe224(index.mantissa, \"new index overflows\");\n supplyState.block = safe32(blockNumber, \"block number overflows\");\n } else if (deltaBlocks > 0) {\n supplyState.block = safe32(blockNumber, \"block number overflows\");\n }\n }\n\n /**\n * @dev Queries the current borrow to calculate rewards for an account\n * @param borrowState VenusMarketState struct\n * @param vToken Address of a vToken\n * @param comptroller Address of the comptroller proxy\n */\n function updateVenusBorrowIndex(\n VenusMarketState memory borrowState,\n address vToken,\n Exp memory marketBorrowIndex,\n ComptrollerInterface comptroller\n ) internal view {\n uint borrowSpeed = comptroller.venusBorrowSpeeds(vToken);\n uint blockNumber = block.number;\n uint deltaBlocks = sub_(blockNumber, uint(borrowState.block));\n if (deltaBlocks > 0 && borrowSpeed > 0) {\n uint borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint venusAccrued = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount > 0 ? fraction(venusAccrued, borrowAmount) : Double({ mantissa: 0 });\n Double memory index = add_(Double({ mantissa: borrowState.index }), ratio);\n borrowState.index = safe224(index.mantissa, \"new index overflows\");\n borrowState.block = safe32(blockNumber, \"block number overflows\");\n } else if (deltaBlocks > 0) {\n borrowState.block = safe32(blockNumber, \"block number overflows\");\n }\n }\n\n /**\n * @dev Calculate available rewards for an account's supply\n * @param supplyState VenusMarketState struct\n * @param vToken Address of a vToken\n * @param supplier Address of the account supplying\n * @param comptroller Address of the comptroller proxy\n * @return Undistributed earned XVS from supplies\n */\n function distributeSupplierVenus(\n VenusMarketState memory supplyState,\n address vToken,\n address supplier,\n ComptrollerInterface comptroller\n ) internal view returns (uint) {\n Double memory supplyIndex = Double({ mantissa: supplyState.index });\n Double memory supplierIndex = Double({ mantissa: comptroller.venusSupplierIndex(vToken, supplier) });\n if (supplierIndex.mantissa == 0 && supplyIndex.mantissa > 0) {\n supplierIndex.mantissa = comptroller.venusInitialIndex();\n }\n\n Double memory deltaIndex = sub_(supplyIndex, supplierIndex);\n uint supplierTokens = VToken(vToken).balanceOf(supplier);\n uint supplierDelta = mul_(supplierTokens, deltaIndex);\n return supplierDelta;\n }\n\n /**\n * @dev Calculate available rewards for an account's borrows\n * @param borrowState VenusMarketState struct\n * @param vToken Address of a vToken\n * @param borrower Address of the account borrowing\n * @param marketBorrowIndex vToken Borrow index\n * @param comptroller Address of the comptroller proxy\n * @return Undistributed earned XVS from borrows\n */\n function distributeBorrowerVenus(\n VenusMarketState memory borrowState,\n address vToken,\n address borrower,\n Exp memory marketBorrowIndex,\n ComptrollerInterface comptroller\n ) internal view returns (uint) {\n Double memory borrowIndex = Double({ mantissa: borrowState.index });\n Double memory borrowerIndex = Double({ mantissa: comptroller.venusBorrowerIndex(vToken, borrower) });\n if (borrowerIndex.mantissa > 0) {\n Double memory deltaIndex = sub_(borrowIndex, borrowerIndex);\n uint borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\n uint borrowerDelta = mul_(borrowerAmount, deltaIndex);\n return borrowerDelta;\n }\n return 0;\n }\n\n /**\n * @notice Calculate the total XVS tokens pending and accrued by a user account\n * @param holder Account to query pending XVS\n * @param comptroller Address of the comptroller\n * @return Reward object contraining the totalRewards and pending rewards for each market\n */\n function pendingRewards(\n address holder,\n ComptrollerInterface comptroller\n ) external view returns (RewardSummary memory) {\n VToken[] memory vTokens = comptroller.getAllMarkets();\n ClaimVenusLocalVariables memory vars;\n RewardSummary memory rewardSummary;\n rewardSummary.distributorAddress = address(comptroller);\n rewardSummary.rewardTokenAddress = comptroller.getXVSAddress();\n rewardSummary.totalRewards = comptroller.venusAccrued(holder);\n rewardSummary.pendingRewards = new PendingReward[](vTokens.length);\n for (uint i; i < vTokens.length; ++i) {\n (vars.borrowIndex, vars.borrowBlock) = comptroller.venusBorrowState(address(vTokens[i]));\n VenusMarketState memory borrowState = VenusMarketState({\n index: vars.borrowIndex,\n block: vars.borrowBlock\n });\n\n (vars.supplyIndex, vars.supplyBlock) = comptroller.venusSupplyState(address(vTokens[i]));\n VenusMarketState memory supplyState = VenusMarketState({\n index: vars.supplyIndex,\n block: vars.supplyBlock\n });\n\n Exp memory borrowIndex = Exp({ mantissa: vTokens[i].borrowIndex() });\n\n PendingReward memory marketReward;\n marketReward.vTokenAddress = address(vTokens[i]);\n\n updateVenusBorrowIndex(borrowState, address(vTokens[i]), borrowIndex, comptroller);\n uint256 borrowReward = distributeBorrowerVenus(\n borrowState,\n address(vTokens[i]),\n holder,\n borrowIndex,\n comptroller\n );\n\n updateVenusSupplyIndex(supplyState, address(vTokens[i]), comptroller);\n uint256 supplyReward = distributeSupplierVenus(supplyState, address(vTokens[i]), holder, comptroller);\n\n marketReward.amount = add_(borrowReward, supplyReward);\n rewardSummary.pendingRewards[i] = marketReward;\n }\n return rewardSummary;\n }\n\n // utilities\n /**\n * @notice Compares if two strings are equal\n * @param a First string to compare\n * @param b Second string to compare\n * @return Boolean depending on if the strings are equal\n */\n function compareStrings(string memory a, string memory b) internal pure returns (bool) {\n return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));\n }\n}\n" + }, + "contracts/Oracle/PriceOracle.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VToken.sol\";\n\ncontract PriceOracle {\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\n bool public constant isPriceOracle = true;\n\n /**\n * @notice Get the underlying price of a vToken asset\n * @param vToken The vToken to get the underlying price of\n * @return The underlying asset price mantissa (scaled by 1e18).\n * Zero means the price is unavailable.\n */\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\n}\n" + }, + "contracts/test/BEP20.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\n\n// Mock import\nimport { GovernorBravoDelegate } from \"@venusprotocol/governance-contracts/contracts/Governance/GovernorBravoDelegate.sol\";\n\ninterface BEP20Base {\n event Approval(address indexed owner, address indexed spender, uint256 value);\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n function totalSupply() external view returns (uint256);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function balanceOf(address who) external view returns (uint256);\n}\n\ncontract BEP20 is BEP20Base {\n function transfer(address to, uint256 value) external returns (bool);\n\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n\ncontract BEP20NS is BEP20Base {\n function transfer(address to, uint256 value) external;\n\n function transferFrom(address from, address to, uint256 value) external;\n}\n\n/**\n * @title Standard BEP20 token\n * @dev Implementation of the basic standard token.\n * See https://github.com/ethereum/EIPs/issues/20\n */\ncontract StandardToken is BEP20 {\n using SafeMath for uint256;\n\n string public name;\n string public symbol;\n uint8 public decimals;\n uint256 public totalSupply;\n mapping(address => mapping(address => uint256)) public allowance;\n mapping(address => uint256) public balanceOf;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public {\n totalSupply = _initialAmount;\n balanceOf[msg.sender] = _initialAmount;\n name = _tokenName;\n symbol = _tokenSymbol;\n decimals = _decimalUnits;\n }\n\n function transfer(address dst, uint256 amount) external returns (bool) {\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(address src, address dst, uint256 amount) external returns (bool) {\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount, \"Insufficient allowance\");\n balanceOf[src] = balanceOf[src].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(src, dst, amount);\n return true;\n }\n\n function approve(address _spender, uint256 amount) external returns (bool) {\n allowance[msg.sender][_spender] = amount;\n emit Approval(msg.sender, _spender, amount);\n return true;\n }\n}\n\n/**\n * @title Non-Standard BEP20 token\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\ncontract NonStandardToken is BEP20NS {\n using SafeMath for uint256;\n\n string public name;\n uint8 public decimals;\n string public symbol;\n uint256 public totalSupply;\n mapping(address => mapping(address => uint256)) public allowance;\n mapping(address => uint256) public balanceOf;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public {\n totalSupply = _initialAmount;\n balanceOf[msg.sender] = _initialAmount;\n name = _tokenName;\n symbol = _tokenSymbol;\n decimals = _decimalUnits;\n }\n\n function transfer(address dst, uint256 amount) external {\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(msg.sender, dst, amount);\n }\n\n function transferFrom(address src, address dst, uint256 amount) external {\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount, \"Insufficient allowance\");\n balanceOf[src] = balanceOf[src].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(src, dst, amount);\n }\n\n function approve(address _spender, uint256 amount) external returns (bool) {\n allowance[msg.sender][_spender] = amount;\n emit Approval(msg.sender, _spender, amount);\n return true;\n }\n}\n\ncontract BEP20Harness is StandardToken {\n // To support testing, we can specify addresses for which transferFrom should fail and return false\n mapping(address => bool) public failTransferFromAddresses;\n\n // To support testing, we allow the contract to always fail `transfer`.\n mapping(address => bool) public failTransferToAddresses;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public StandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {}\n\n function harnessSetFailTransferFromAddress(address src, bool _fail) public {\n failTransferFromAddresses[src] = _fail;\n }\n\n function harnessSetFailTransferToAddress(address dst, bool _fail) public {\n failTransferToAddresses[dst] = _fail;\n }\n\n function harnessSetBalance(address _account, uint _amount) public {\n balanceOf[_account] = _amount;\n }\n\n function transfer(address dst, uint256 amount) external returns (bool success) {\n // Added for testing purposes\n if (failTransferToAddresses[dst]) {\n return false;\n }\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success) {\n // Added for testing purposes\n if (failTransferFromAddresses[src]) {\n return false;\n }\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount, \"Insufficient allowance\");\n balanceOf[src] = balanceOf[src].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(src, dst, amount);\n return true;\n }\n}\n" + }, + "contracts/test/ComptrollerHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./ComptrollerMock.sol\";\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Comptroller/Unitroller.sol\";\n\ncontract ComptrollerHarness is ComptrollerMock {\n address internal xvsAddress;\n address internal vXVSAddress;\n uint public blockNumber;\n\n constructor() public ComptrollerMock() {}\n\n function setVenusSupplyState(address vToken, uint224 index, uint32 blockNumber_) public {\n venusSupplyState[vToken].index = index;\n venusSupplyState[vToken].block = blockNumber_;\n }\n\n function setVenusBorrowState(address vToken, uint224 index, uint32 blockNumber_) public {\n venusBorrowState[vToken].index = index;\n venusBorrowState[vToken].block = blockNumber_;\n }\n\n function setVenusAccrued(address user, uint userAccrued) public {\n venusAccrued[user] = userAccrued;\n }\n\n function setXVSAddress(address xvsAddress_) public {\n xvsAddress = xvsAddress_;\n }\n\n function setXVSVTokenAddress(address vXVSAddress_) public {\n vXVSAddress = vXVSAddress_;\n }\n\n /**\n * @notice Set the amount of XVS distributed per block\n * @param venusRate_ The amount of XVS wei per block to distribute\n */\n function harnessSetVenusRate(uint venusRate_) public {\n venusRate = venusRate_;\n }\n\n /**\n * @notice Recalculate and update XVS speeds for all XVS markets\n */\n function harnessRefreshVenusSpeeds() public {\n VToken[] memory allMarkets_ = allMarkets;\n\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets_[i];\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n updateVenusSupplyIndex(address(vToken));\n updateVenusBorrowIndex(address(vToken), borrowIndex);\n }\n\n Exp memory totalUtility = Exp({ mantissa: 0 });\n Exp[] memory utilities = new Exp[](allMarkets_.length);\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets_[i];\n if (venusSpeeds[address(vToken)] > 0) {\n Exp memory assetPrice = Exp({ mantissa: oracle.getUnderlyingPrice(vToken) });\n Exp memory utility = mul_(assetPrice, vToken.totalBorrows());\n utilities[i] = utility;\n totalUtility = add_(totalUtility, utility);\n }\n }\n\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets[i];\n uint newSpeed = totalUtility.mantissa > 0 ? mul_(venusRate, div_(utilities[i], totalUtility)) : 0;\n setVenusSpeedInternal(vToken, newSpeed, newSpeed);\n }\n }\n\n function setVenusBorrowerIndex(address vToken, address borrower, uint index) public {\n venusBorrowerIndex[vToken][borrower] = index;\n }\n\n function setVenusSupplierIndex(address vToken, address supplier, uint index) public {\n venusSupplierIndex[vToken][supplier] = index;\n }\n\n function harnessDistributeAllBorrowerVenus(\n address vToken,\n address borrower,\n uint marketBorrowIndexMantissa\n ) public {\n distributeBorrowerVenus(vToken, borrower, Exp({ mantissa: marketBorrowIndexMantissa }));\n venusAccrued[borrower] = grantXVSInternal(borrower, venusAccrued[borrower], 0, false);\n }\n\n function harnessDistributeAllSupplierVenus(address vToken, address supplier) public {\n distributeSupplierVenus(vToken, supplier);\n venusAccrued[supplier] = grantXVSInternal(supplier, venusAccrued[supplier], 0, false);\n }\n\n function harnessUpdateVenusBorrowIndex(address vToken, uint marketBorrowIndexMantissa) public {\n updateVenusBorrowIndex(vToken, Exp({ mantissa: marketBorrowIndexMantissa }));\n }\n\n function harnessUpdateVenusSupplyIndex(address vToken) public {\n updateVenusSupplyIndex(vToken);\n }\n\n function harnessDistributeBorrowerVenus(address vToken, address borrower, uint marketBorrowIndexMantissa) public {\n distributeBorrowerVenus(vToken, borrower, Exp({ mantissa: marketBorrowIndexMantissa }));\n }\n\n function harnessDistributeSupplierVenus(address vToken, address supplier) public {\n distributeSupplierVenus(vToken, supplier);\n }\n\n function harnessTransferVenus(address user, uint userAccrued, uint threshold) public returns (uint) {\n if (userAccrued > 0 && userAccrued >= threshold) {\n return grantXVSInternal(user, userAccrued, 0, false);\n }\n return userAccrued;\n }\n\n function harnessAddVenusMarkets(address[] memory vTokens) public {\n for (uint i = 0; i < vTokens.length; i++) {\n // temporarily set venusSpeed to 1 (will be fixed by `harnessRefreshVenusSpeeds`)\n setVenusSpeedInternal(VToken(vTokens[i]), 1, 1);\n }\n }\n\n function harnessSetMintedVAIs(address user, uint amount) public {\n mintedVAIs[user] = amount;\n }\n\n function harnessFastForward(uint blocks) public returns (uint) {\n blockNumber += blocks;\n return blockNumber;\n }\n\n function setBlockNumber(uint number) public {\n blockNumber = number;\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getVenusMarkets() public view returns (address[] memory) {\n uint m = allMarkets.length;\n uint n = 0;\n for (uint i = 0; i < m; i++) {\n if (venusSpeeds[address(allMarkets[i])] > 0) {\n n++;\n }\n }\n\n address[] memory venusMarkets = new address[](n);\n uint k = 0;\n for (uint i = 0; i < m; i++) {\n if (venusSpeeds[address(allMarkets[i])] > 0) {\n venusMarkets[k++] = address(allMarkets[i]);\n }\n }\n return venusMarkets;\n }\n\n function harnessSetReleaseStartBlock(uint startBlock) external {\n releaseStartBlock = startBlock;\n }\n\n function harnessAddVtoken(address vToken) external {\n markets[vToken] = Market({ isListed: true, isVenus: false, collateralFactorMantissa: 0 });\n }\n}\n\ncontract EchoTypesComptroller is UnitrollerAdminStorage {\n function stringy(string memory s) public pure returns (string memory) {\n return s;\n }\n\n function addresses(address a) public pure returns (address) {\n return a;\n }\n\n function booly(bool b) public pure returns (bool) {\n return b;\n }\n\n function listOInts(uint[] memory u) public pure returns (uint[] memory) {\n return u;\n }\n\n function reverty() public pure {\n require(false, \"gotcha sucka\");\n }\n\n function becomeBrains(address payable unitroller) public {\n Unitroller(unitroller)._acceptImplementation();\n }\n}\n" + }, + "contracts/test/ComptrollerMock.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Comptroller/Diamond/facets/MarketFacet.sol\";\nimport \"../Comptroller/Diamond/facets/PolicyFacet.sol\";\nimport \"../Comptroller/Diamond/facets/RewardFacet.sol\";\nimport \"../Comptroller/Diamond/facets/SetterFacet.sol\";\nimport \"../Comptroller/Unitroller.sol\";\n\n// This contract contains all methods of Comptroller implementation in different facets at one place for testing purpose\n// This contract does not have diamond functionality(i.e delegate call to facets methods)\ncontract ComptrollerMock is MarketFacet, PolicyFacet, RewardFacet, SetterFacet {\n constructor() public {\n admin = msg.sender;\n }\n\n function _become(Unitroller unitroller) public {\n require(msg.sender == unitroller.admin(), \"only unitroller admin can\");\n require(unitroller._acceptImplementation() == 0, \"not authorized\");\n }\n\n function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint) {\n ensureAdmin();\n ensureNonzeroAddress(address(comptrollerLens_));\n address oldComptrollerLens = address(comptrollerLens);\n comptrollerLens = comptrollerLens_;\n emit NewComptrollerLens(oldComptrollerLens, address(comptrollerLens));\n\n return uint(Error.NO_ERROR);\n }\n}\n" + }, + "contracts/test/ComptrollerScenario.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./ComptrollerMock.sol\";\n\ncontract ComptrollerScenario is ComptrollerMock {\n uint public blockNumber;\n address public xvsAddress;\n address public vaiAddress;\n\n constructor() public ComptrollerMock() {}\n\n function setXVSAddress(address xvsAddress_) public {\n xvsAddress = xvsAddress_;\n }\n\n // function getXVSAddress() public view returns (address) {\n // return xvsAddress;\n // }\n\n function setVAIAddress(address vaiAddress_) public {\n vaiAddress = vaiAddress_;\n }\n\n function getVAIAddress() public view returns (address) {\n return vaiAddress;\n }\n\n function membershipLength(VToken vToken) public view returns (uint) {\n return accountAssets[address(vToken)].length;\n }\n\n function fastForward(uint blocks) public returns (uint) {\n blockNumber += blocks;\n\n return blockNumber;\n }\n\n function setBlockNumber(uint number) public {\n blockNumber = number;\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getVenusMarkets() public view returns (address[] memory) {\n uint m = allMarkets.length;\n uint n = 0;\n for (uint i = 0; i < m; i++) {\n if (markets[address(allMarkets[i])].isVenus) {\n n++;\n }\n }\n\n address[] memory venusMarkets = new address[](n);\n uint k = 0;\n for (uint i = 0; i < m; i++) {\n if (markets[address(allMarkets[i])].isVenus) {\n venusMarkets[k++] = address(allMarkets[i]);\n }\n }\n return venusMarkets;\n }\n\n function unlist(VToken vToken) public {\n markets[address(vToken)].isListed = false;\n }\n\n /**\n * @notice Recalculate and update XVS speeds for all XVS markets\n */\n function refreshVenusSpeeds() public {\n VToken[] memory allMarkets_ = allMarkets;\n\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets_[i];\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n updateVenusSupplyIndex(address(vToken));\n updateVenusBorrowIndex(address(vToken), borrowIndex);\n }\n\n Exp memory totalUtility = Exp({ mantissa: 0 });\n Exp[] memory utilities = new Exp[](allMarkets_.length);\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets_[i];\n if (venusSpeeds[address(vToken)] > 0) {\n Exp memory assetPrice = Exp({ mantissa: oracle.getUnderlyingPrice(vToken) });\n Exp memory utility = mul_(assetPrice, vToken.totalBorrows());\n utilities[i] = utility;\n totalUtility = add_(totalUtility, utility);\n }\n }\n\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets[i];\n uint newSpeed = totalUtility.mantissa > 0 ? mul_(venusRate, div_(utilities[i], totalUtility)) : 0;\n setVenusSpeedInternal(vToken, newSpeed, newSpeed);\n }\n }\n}\n" + }, + "contracts/test/DiamondHarness.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Comptroller/Diamond/Diamond.sol\";\n\ncontract DiamondHarness is Diamond {\n function getFacetAddress(bytes4 sig) public view returns (address) {\n address facet = _selectorToFacetAndPosition[sig].facetAddress;\n require(facet != address(0), \"Diamond: Function does not exist\");\n return facet;\n }\n}\n" + }, + "contracts/test/EvilToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./FaucetToken.sol\";\n\n/**\n * @title The Venus Evil Test Token\n * @author Venus\n * @notice A simple test token that fails certain operations\n */\ncontract EvilToken is FaucetToken {\n bool public fail;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public FaucetToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {\n fail = true;\n }\n\n function setFail(bool _fail) external {\n fail = _fail;\n }\n\n function transfer(address dst, uint256 amount) external returns (bool) {\n if (fail) {\n return false;\n }\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount);\n balanceOf[dst] = balanceOf[dst].add(amount);\n emit Transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(address src, address dst, uint256 amount) external returns (bool) {\n if (fail) {\n return false;\n }\n balanceOf[src] = balanceOf[src].sub(amount);\n balanceOf[dst] = balanceOf[dst].add(amount);\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount);\n emit Transfer(src, dst, amount);\n return true;\n }\n}\n" + }, + "contracts/test/EvilXDelegator.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VTokenInterfaces.sol\";\n\n/**\n * @title Venus's VBep20Delegator Contract\n * @notice VTokens which wrap an EIP-20 underlying and delegate to an implementation\n * @author Venus\n */\ncontract EvilXDelegator is VTokenInterface, VBep20Interface, VDelegatorInterface {\n /**\n * @notice Construct a new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param implementation_ The address of the implementation the contract delegates to\n * @param becomeImplementationData The encoded args for becomeImplementation\n */\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint256 initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_,\n address implementation_,\n bytes memory becomeImplementationData\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(\n implementation_,\n abi.encodeWithSignature(\n \"initialize(address,address,address,uint256,string,string,uint8)\",\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_\n )\n );\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_, false, becomeImplementationData);\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\n */\n function _setImplementation(\n address implementation_,\n bool allowResign,\n bytes memory becomeImplementationData\n ) public {\n require(msg.sender == admin, \"VBep20Delegator::_setImplementation: Caller must be admin\");\n\n if (allowResign) {\n delegateToImplementation(abi.encodeWithSignature(\"_resignImplementation()\"));\n }\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n delegateToImplementation(abi.encodeWithSignature(\"_becomeImplementation(bytes)\", becomeImplementationData));\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function mint(uint256 mintAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"mint(uint256)\", mintAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function mintBehalf(address receiver, uint256 mintAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"mintBehalf(address,uint256)\", receiver, mintAmount)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function redeem(uint256 redeemTokens) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"redeem(uint256)\", redeemTokens));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function redeemUnderlying(uint256 redeemAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"redeemUnderlying(uint256)\", redeemAmount)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function borrow(uint256 borrowAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrow(uint256)\", borrowAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function repayBorrow(uint256 repayAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"repayBorrow(uint256)\", repayAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender repays a borrow belonging to borrower\n * @param borrower the account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"repayBorrowBehalf(address,uint256)\", borrower, repayAmount)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function liquidateBorrow(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"liquidateBorrow(address,uint256,address)\", borrower, repayAmount, vTokenCollateral)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"transfer(address,uint256)\", dst, amount));\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"transferFrom(address,address,uint256)\", src, dst, amount)\n );\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved (-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"approve(address,uint256)\", spender, amount)\n );\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return The number of tokens allowed to be spent (-1 means infinite)\n */\n function allowance(address owner, address spender) external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"allowance(address,address)\", owner, spender)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Get the token balance of the `owner`\n * @param owner The address of the account to query\n * @return The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"balanceOf(address)\", owner));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Get the underlying balance of the `owner`\n * @dev This also accrues interest in a transaction\n * @param owner The address of the account to query\n * @return The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"balanceOfUnderlying(address)\", owner));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\n * @param account Address of the account to snapshot\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\n */\n function getAccountSnapshot(address account) external view returns (uint256, uint256, uint256, uint256) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"getAccountSnapshot(address)\", account)\n );\n return abi.decode(data, (uint256, uint256, uint256, uint256));\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"borrowRatePerBlock()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this vToken\n * @return The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"supplyRatePerBlock()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return The total borrows with interest\n */\n function totalBorrowsCurrent() external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"totalBorrowsCurrent()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\n * @param account The address whose balance should be calculated after updating borrowIndex\n * @return The calculated balance\n */\n function borrowBalanceCurrent(address account) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrowBalanceCurrent(address)\", account));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Return the borrow balance of account based on stored data\n * @param account The address whose balance should be calculated\n * @return The calculated balance\n */\n function borrowBalanceStored(address account) public view returns (uint256) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"borrowBalanceStored(address)\", account)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"exchangeRateCurrent()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Calculates the exchange rate from the underlying to the VToken\n * @dev This function does not accrue interest before calculating the exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() public view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"exchangeRateStored()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return The quantity of underlying asset owned by this contract\n */\n function getCash() external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"getCash()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Applies accrued interest to total borrows and reserves.\n * @dev This calculates interest accrued from the last checkpointed block\n * up to the current block and writes new checkpoint to storage.\n */\n function accrueInterest() public returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"accrueInterest()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Transfers collateral tokens (this market) to the liquidator.\n * @dev Will fail unless called by another vToken during the process of liquidation.\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\n * @param liquidator The account receiving seized collateral\n * @param borrower The account having collateral seized\n * @param seizeTokens The number of vTokens to seize\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function seize(address liquidator, address borrower, uint256 seizeTokens) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"seize(address,address,uint256)\", liquidator, borrower, seizeTokens)\n );\n return abi.decode(data, (uint256));\n }\n\n /*** Admin Functions ***/\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setPendingAdmin(address)\", newPendingAdmin)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sets a new comptroller for the market\n * @dev Admin function to set a new comptroller\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setComptroller(address)\", newComptroller)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh\n * @dev Admin function to accrue interest and set a new reserve factor\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setReserveFactor(uint256 newReserveFactorMantissa) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setReserveFactor(uint256)\", newReserveFactorMantissa)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_acceptAdmin()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrues interest and adds reserves by transferring from admin\n * @param addAmount Amount of reserves to add\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _addReserves(uint256 addAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_addReserves(uint256)\", addAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to admin\n * @param reduceAmount Amount of reduction to reserves\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _reduceReserves(uint256 reduceAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_reduceReserves(uint256)\", reduceAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\n * @dev Admin function to accrue interest and update the interest rate model\n * @param newInterestRateModel the new interest rate model to use\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setInterestRateModel(address)\", newInterestRateModel)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n\n /**\n * @notice Delegates execution to the implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateToImplementation(bytes memory data) public returns (bytes memory) {\n return delegateTo(implementation, data);\n }\n\n /**\n * @notice Delegates execution to an implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * There are an additional 2 prefix uints from the wrapper returndata, which we ignore since we make an extra hop.\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateToViewImplementation(bytes memory data) public view returns (bytes memory) {\n (bool success, bytes memory returnData) = address(this).staticcall(\n abi.encodeWithSignature(\"delegateToImplementation(bytes)\", data)\n );\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return abi.decode(returnData, (bytes));\n }\n\n /**\n * @notice Delegates execution to an implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n */\n function() external payable {\n require(msg.value == 0, \"VBep20Delegator:fallback: cannot send value to fallback\");\n\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/test/EvilXToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VBep20Immutable.sol\";\nimport \"../Tokens/VTokens/VBep20Delegator.sol\";\nimport \"../Tokens/VTokens/VBep20Delegate.sol\";\nimport \"./ComptrollerScenario.sol\";\nimport \"../Comptroller/ComptrollerInterface.sol\";\n\ncontract VBep20Scenario is VBep20Immutable {\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n )\n public\n VBep20Immutable(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_\n )\n {}\n\n function setTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function setTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function getBlockNumber() internal view returns (uint) {\n ComptrollerScenario comptrollerScenario = ComptrollerScenario(address(comptroller));\n return comptrollerScenario.blockNumber();\n }\n}\n\n// doTransferOut method of this token supposed to be compromised and contians malicious code which\n// can be used by attacker to compromise the protocol working.\ncontract EvilXToken is VBep20Delegate {\n event Log(string x, address y);\n event Log(string x, uint y);\n event LogLiquidity(uint liquidity);\n\n uint internal blockNumber = 100000;\n uint internal harnessExchangeRate;\n bool internal harnessExchangeRateStored;\n\n address public comptrollerAddress;\n\n mapping(address => bool) public failTransferToAddresses;\n\n function setComptrollerAddress(address _comptrollerAddress) external {\n comptrollerAddress = _comptrollerAddress;\n }\n\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\n if (harnessExchangeRateStored) {\n return (MathError.NO_ERROR, harnessExchangeRate);\n }\n return super.exchangeRateStoredInternal();\n }\n\n function doTransferOut(address payable to, uint amount) internal {\n require(failTransferToAddresses[to] == false, \"TOKEN_TRANSFER_OUT_FAILED\");\n super.doTransferOut(to, amount);\n\n // Checking the Liquidity of the user after the tranfer.\n // solhint-disable-next-line no-unused-vars\n (uint errorCode, uint liquidity, uint shortfall) = ComptrollerInterface(comptrollerAddress).getAccountLiquidity(\n msg.sender\n );\n emit LogLiquidity(liquidity);\n return;\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getBorrowRateMaxMantissa() public pure returns (uint) {\n return borrowRateMaxMantissa;\n }\n\n function harnessSetBlockNumber(uint newBlockNumber) public {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetAccrualBlockNumber(uint _accrualblockNumber) public {\n accrualBlockNumber = _accrualblockNumber;\n }\n\n function harnessSetTotalSupply(uint totalSupply_) public {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function harnessIncrementTotalBorrows(uint addtlBorrow_) public {\n totalBorrows = totalBorrows + addtlBorrow_;\n }\n\n function harnessSetTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(uint totalSupply_, uint totalBorrows_, uint totalReserves_) public {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint exchangeRate) public {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address _to, bool _fail) public {\n failTransferToAddresses[_to] = _fail;\n }\n\n function harnessMintFresh(address account, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintFresh(account, mintAmount);\n return err;\n }\n\n function harnessMintBehalfFresh(address payer, address receiver, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintBehalfFresh(payer, receiver, mintAmount);\n return err;\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint vTokenAmount,\n uint underlyingAmount\n ) public returns (uint) {\n return super.redeemFresh(account, account, vTokenAmount, underlyingAmount);\n }\n\n function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function harnessSetAccountBorrows(address account, uint principal, uint interestIndex) public {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint borrowIndex_) public {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint borrowAmount) public returns (uint) {\n return borrowFresh(account, account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(address payer, address account, uint repayAmount) public returns (uint) {\n (uint err, ) = repayBorrowFresh(payer, account, repayAmount);\n return err;\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VToken vTokenCollateral\n ) public returns (uint) {\n (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n function harnessReduceReservesFresh(uint amount) public returns (uint) {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint newReserveFactorMantissa) public returns (uint) {\n return _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) public returns (uint) {\n return _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallBorrowAllowed(uint amount) public returns (uint) {\n return comptroller.borrowAllowed(address(this), msg.sender, amount);\n }\n}\n" + }, + "contracts/test/Fauceteer.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/EIP20NonStandardInterface.sol\";\n\n/**\n * @title Fauceteer\n * @author Venus\n * @notice First computer program to be part of The Giving Pledge\n */\ncontract Fauceteer {\n /**\n * @notice Drips some tokens to caller\n * @dev We send 0.01% of our tokens to the caller. Over time, the amount will tend toward and eventually reach zero.\n * @param token The token to drip. Note: if we have no balance in this token, function will revert.\n */\n function drip(EIP20NonStandardInterface token) public {\n uint tokenBalance = token.balanceOf(address(this));\n require(tokenBalance > 0, \"Fauceteer is empty\");\n token.transfer(msg.sender, tokenBalance / 10000); // 0.01%\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a compliant BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n\n require(success, \"Transfer returned false.\");\n }\n}\n" + }, + "contracts/test/FaucetToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./BEP20.sol\";\n\n/**\n * @title The Venus Faucet Test Token\n * @author Venus\n * @notice A simple test token that lets anyone get more of it.\n */\ncontract FaucetToken is StandardToken {\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public StandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {}\n\n function allocateTo(address _owner, uint256 value) public {\n balanceOf[_owner] += value;\n totalSupply += value;\n emit Transfer(address(this), _owner, value);\n }\n}\n\n/**\n * @title The Venus Faucet Test Token (non-standard)\n * @author Venus\n * @notice A simple test token that lets anyone get more of it.\n */\ncontract FaucetNonStandardToken is NonStandardToken {\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public NonStandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {}\n\n function allocateTo(address _owner, uint256 value) public {\n balanceOf[_owner] += value;\n totalSupply += value;\n emit Transfer(address(this), _owner, value);\n }\n}\n\n/**\n * @title The Venus Faucet Re-Entrant Test Token\n * @author Venus\n * @notice A test token that is malicious and tries to re-enter callers\n */\ncontract FaucetTokenReEntrantHarness {\n using SafeMath for uint256;\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n string public name;\n string public symbol;\n uint8 public decimals;\n uint256 internal totalSupply_;\n mapping(address => mapping(address => uint256)) internal allowance_;\n mapping(address => uint256) internal balanceOf_;\n\n bytes public reEntryCallData;\n string public reEntryFun;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol,\n bytes memory _reEntryCallData,\n string memory _reEntryFun\n ) public {\n totalSupply_ = _initialAmount;\n balanceOf_[msg.sender] = _initialAmount;\n name = _tokenName;\n symbol = _tokenSymbol;\n decimals = _decimalUnits;\n reEntryCallData = _reEntryCallData;\n reEntryFun = _reEntryFun;\n }\n\n modifier reEnter(string memory funName) {\n string memory _reEntryFun = reEntryFun;\n if (compareStrings(_reEntryFun, funName)) {\n reEntryFun = \"\"; // Clear re-entry fun\n (bool success, bytes memory returndata) = msg.sender.call(reEntryCallData);\n assembly {\n if eq(success, 0) {\n revert(add(returndata, 0x20), returndatasize())\n }\n }\n }\n\n _;\n }\n\n function compareStrings(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)));\n }\n\n function allocateTo(address _owner, uint256 value) public {\n balanceOf_[_owner] += value;\n totalSupply_ += value;\n emit Transfer(address(this), _owner, value);\n }\n\n function totalSupply() public reEnter(\"totalSupply\") returns (uint256) {\n return totalSupply_;\n }\n\n function allowance(address owner, address spender) public reEnter(\"allowance\") returns (uint256 remaining) {\n return allowance_[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public reEnter(\"approve\") returns (bool success) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function balanceOf(address owner) public reEnter(\"balanceOf\") returns (uint256 balance) {\n return balanceOf_[owner];\n }\n\n function transfer(address dst, uint256 amount) public reEnter(\"transfer\") returns (bool success) {\n _transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) public reEnter(\"transferFrom\") returns (bool success) {\n _transfer(src, dst, amount);\n _approve(src, msg.sender, allowance_[src][msg.sender].sub(amount));\n return true;\n }\n\n function _approve(address owner, address spender, uint256 amount) internal {\n require(spender != address(0), \"sender should be valid address\");\n require(owner != address(0), \"owner should be valid address\");\n allowance_[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _transfer(address src, address dst, uint256 amount) internal {\n require(dst != address(0), \"dst should be valid address\");\n balanceOf_[src] = balanceOf_[src].sub(amount);\n balanceOf_[dst] = balanceOf_[dst].add(amount);\n emit Transfer(src, dst, amount);\n }\n}\n" + }, + "contracts/test/FeeToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./FaucetToken.sol\";\n\n/**\n * @title Fee Token\n * @author Venus\n * @notice A simple test token that charges fees on transfer. Used to mock USDT.\n */\ncontract FeeToken is FaucetToken {\n uint public basisPointFee;\n address public owner;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol,\n uint _basisPointFee,\n address _owner\n ) public FaucetToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {\n basisPointFee = _basisPointFee;\n owner = _owner;\n }\n\n function transfer(address dst, uint amount) public returns (bool) {\n uint fee = amount.mul(basisPointFee).div(10000);\n uint net = amount.sub(fee);\n balanceOf[owner] = balanceOf[owner].add(fee);\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount);\n balanceOf[dst] = balanceOf[dst].add(net);\n emit Transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(address src, address dst, uint amount) public returns (bool) {\n uint fee = amount.mul(basisPointFee).div(10000);\n uint net = amount.sub(fee);\n balanceOf[owner] = balanceOf[owner].add(fee);\n balanceOf[src] = balanceOf[src].sub(amount);\n balanceOf[dst] = balanceOf[dst].add(net);\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount);\n emit Transfer(src, dst, amount);\n return true;\n }\n}\n" + }, + "contracts/test/FixedPriceOracle.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Oracle/PriceOracle.sol\";\n\ncontract FixedPriceOracle is PriceOracle {\n uint public price;\n\n constructor(uint _price) public {\n price = _price;\n }\n\n function getUnderlyingPrice(VToken vToken) public view returns (uint) {\n vToken;\n return price;\n }\n\n function assetPrices(address asset) public view returns (uint) {\n asset;\n return price;\n }\n}\n" + }, + "contracts/test/InterestRateModelHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../InterestRateModels/InterestRateModel.sol\";\n\n/**\n * @title An Interest Rate Model for tests that can be instructed to return a failure instead of doing a calculation\n * @author Venus\n */\ncontract InterestRateModelHarness is InterestRateModel {\n uint public constant opaqueBorrowFailureCode = 20;\n bool public failBorrowRate;\n uint public borrowRate;\n\n constructor(uint borrowRate_) public {\n borrowRate = borrowRate_;\n }\n\n function setFailBorrowRate(bool failBorrowRate_) public {\n failBorrowRate = failBorrowRate_;\n }\n\n function setBorrowRate(uint borrowRate_) public {\n borrowRate = borrowRate_;\n }\n\n function getBorrowRate(uint _cash, uint _borrows, uint _reserves) public view returns (uint) {\n _cash; // unused\n _borrows; // unused\n _reserves; // unused\n require(!failBorrowRate, \"INTEREST_RATE_MODEL_ERROR\");\n return borrowRate;\n }\n\n function getSupplyRate(\n uint _cash,\n uint _borrows,\n uint _reserves,\n uint _reserveFactor\n ) external view returns (uint) {\n _cash; // unused\n _borrows; // unused\n _reserves; // unused\n return borrowRate * (1 - _reserveFactor);\n }\n}\n" + }, + "contracts/test/MockDeflationaryToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\n\ncontract DeflatingERC20 {\n using SafeMath for uint;\n\n string public constant name = \"Deflating Test Token\";\n string public constant symbol = \"DTT\";\n uint8 public constant decimals = 18;\n uint public totalSupply;\n mapping(address => uint) public balanceOf;\n mapping(address => mapping(address => uint)) public allowance;\n\n bytes32 public DOMAIN_SEPARATOR;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n event Approval(address indexed owner, address indexed spender, uint value);\n event Transfer(address indexed from, address indexed to, uint value);\n\n constructor(uint _totalSupply) public {\n uint chainId;\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n _mint(msg.sender, _totalSupply);\n }\n\n function _mint(address to, uint value) internal {\n totalSupply = totalSupply.add(value);\n balanceOf[to] = balanceOf[to].add(value);\n emit Transfer(address(0), to, value);\n }\n\n function _burn(address from, uint value) internal {\n balanceOf[from] = balanceOf[from].sub(value);\n totalSupply = totalSupply.sub(value);\n emit Transfer(from, address(0), value);\n }\n\n function _approve(address owner, address spender, uint value) private {\n allowance[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _transfer(address from, address to, uint value) private {\n uint burnAmount = value / 100;\n _burn(from, burnAmount);\n uint transferAmount = value.sub(burnAmount);\n balanceOf[from] = balanceOf[from].sub(transferAmount);\n balanceOf[to] = balanceOf[to].add(transferAmount);\n emit Transfer(from, to, transferAmount);\n }\n\n function approve(address spender, uint value) external returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transfer(address to, uint value) external returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint value) external returns (bool) {\n if (allowance[from][msg.sender] != uint(-1)) {\n allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);\n }\n _transfer(from, to, value);\n return true;\n }\n\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"EXPIRED\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n}\n" + }, + "contracts/test/MockVBNB.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VToken.sol\";\n\n/**\n * @title Venus's vBNB Contract\n * @notice vToken which wraps BNB\n * @author Venus\n */\ncontract MockVBNB is VToken {\n /**\n * @notice Construct a new vBNB money market\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n */\n constructor(\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_);\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n\n /**\n * @notice Send BNB to VBNB to mint\n */\n function() external payable {\n (uint err, ) = mintInternal(msg.value);\n requireNoError(err, \"mint failed\");\n }\n\n /*** User Interface ***/\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Reverts upon any failure\n */\n // @custom:event Emits Transfer event\n // @custom:event Emits Mint event\n function mint() external payable {\n (uint err, ) = mintInternal(msg.value);\n requireNoError(err, \"mint failed\");\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeem(uint redeemTokens) external returns (uint) {\n return redeemInternal(msg.sender, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n return redeemUnderlyingInternal(msg.sender, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Borrow event on success\n function borrow(uint borrowAmount) external returns (uint) {\n return borrowInternal(msg.sender, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @dev Reverts upon any failure\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrow() external payable {\n (uint err, ) = repayBorrowInternal(msg.value);\n requireNoError(err, \"repayBorrow failed\");\n }\n\n /**\n * @notice Sender repays a borrow belonging to borrower\n * @dev Reverts upon any failure\n * @param borrower The account with the debt being payed off\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrowBehalf(address borrower) external payable {\n (uint err, ) = repayBorrowBehalfInternal(borrower, msg.value);\n requireNoError(err, \"repayBorrowBehalf failed\");\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @dev Reverts upon any failure\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n */\n // @custom:event Emit LiquidateBorrow event on success\n function liquidateBorrow(address borrower, VToken vTokenCollateral) external payable {\n (uint err, ) = liquidateBorrowInternal(borrower, msg.value, vTokenCollateral);\n requireNoError(err, \"liquidateBorrow failed\");\n }\n\n function setTotalReserves(uint totalReserves_) external payable {\n totalReserves = totalReserves_;\n }\n\n /*** Safe Token ***/\n\n /**\n * @notice Perform the actual transfer in, which is a no-op\n * @param from Address sending the BNB\n * @param amount Amount of BNB being sent\n * @return The actual amount of BNB transferred\n */\n function doTransferIn(address from, uint amount) internal returns (uint) {\n // Sanity checks\n require(msg.sender == from, \"sender mismatch\");\n require(msg.value == amount, \"value mismatch\");\n return amount;\n }\n\n function doTransferOut(address payable to, uint amount) internal {\n /* Send the BNB, with minimal gas and revert on failure */\n to.transfer(amount);\n }\n\n /**\n * @notice Gets balance of this contract in terms of BNB, before this message\n * @dev This excludes the value of the current message, if any\n * @return The quantity of BNB owned by this contract\n */\n function getCashPrior() internal view returns (uint) {\n (MathError err, uint startingBalance) = subUInt(address(this).balance, msg.value);\n require(err == MathError.NO_ERROR, \"cash prior math error\");\n return startingBalance;\n }\n\n function requireNoError(uint errCode, string memory message) internal pure {\n if (errCode == uint(Error.NO_ERROR)) {\n return;\n }\n\n bytes memory fullMessage = new bytes(bytes(message).length + 5);\n uint i;\n\n for (i = 0; i < bytes(message).length; i++) {\n fullMessage[i] = bytes(message)[i];\n }\n\n fullMessage[i + 0] = bytes1(uint8(32));\n fullMessage[i + 1] = bytes1(uint8(40));\n fullMessage[i + 2] = bytes1(uint8(48 + (errCode / 10)));\n fullMessage[i + 3] = bytes1(uint8(48 + (errCode % 10)));\n fullMessage[i + 4] = bytes1(uint8(41));\n\n require(errCode == uint(Error.NO_ERROR), string(fullMessage));\n }\n\n /**\n * @dev Function to simply retrieve block number\n * This exists mainly for inheriting test contracts to stub this result.\n */\n function getBlockNumber() internal view returns (uint) {\n return block.number;\n }\n\n /**\n * @notice Reduces reserves by transferring to admin\n * @dev Requires fresh interest accrual\n * @param reduceAmount Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\n // totalReserves - reduceAmount\n uint totalReservesNew;\n\n // Check caller is admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.REDUCE_RESERVES_ADMIN_CHECK);\n }\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != getBlockNumber()) {\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\n }\n\n // Fail gracefully if protocol has insufficient underlying cash\n if (getCashPrior() < reduceAmount) {\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\n }\n\n // Check reduceAmount ≤ reserves[n] (totalReserves)\n if (reduceAmount > totalReserves) {\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n totalReservesNew = totalReserves - reduceAmount;\n\n // Store reserves[n+1] = reserves[n] - reduceAmount\n totalReserves = totalReservesNew;\n\n // // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\n doTransferOut(admin, reduceAmount);\n\n emit ReservesReduced(admin, reduceAmount, totalReservesNew);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to admin\n * @param reduceAmount Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits ReservesReduced event\n function _reduceReserves(uint reduceAmount) external nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\n }\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\n return _reduceReservesFresh(reduceAmount);\n }\n\n /**\n * @notice Applies accrued interest to total borrows and reserves\n * @dev This calculates interest accrued from the last checkpointed block\n * up to the current block and writes new checkpoint to storage.\n */\n // @custom:event Emits AccrueInterest event\n function accrueInterest() public returns (uint) {\n /* Remember the initial block number */\n uint currentBlockNumber = getBlockNumber();\n uint accrualBlockNumberPrior = accrualBlockNumber;\n\n /* Short-circuit accumulating 0 interest */\n if (accrualBlockNumberPrior == currentBlockNumber) {\n return uint(Error.NO_ERROR);\n }\n\n /* Read the previous values out of storage */\n uint cashPrior = getCashPrior();\n uint borrowsPrior = totalBorrows;\n uint reservesPrior = totalReserves;\n uint borrowIndexPrior = borrowIndex;\n\n /* Calculate the current borrow interest rate */\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\n require(borrowRateMantissa <= borrowRateMaxMantissa, \"borrow rate is absurdly high\");\n\n /* Calculate the number of blocks elapsed since the last accrual */\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\n require(mathErr == MathError.NO_ERROR, \"could not calculate block delta\");\n\n /*\n * Calculate the interest accumulated into borrows and reserves and the new index:\n * simpleInterestFactor = borrowRate * blockDelta\n * interestAccumulated = simpleInterestFactor * totalBorrows\n * totalBorrowsNew = interestAccumulated + totalBorrows\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\n */\n\n Exp memory simpleInterestFactor;\n uint interestAccumulated;\n uint totalBorrowsNew;\n uint totalReservesNew;\n uint borrowIndexNew;\n\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\n Exp({ mantissa: reserveFactorMantissa }),\n interestAccumulated,\n reservesPrior\n );\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the previously calculated values into storage */\n accrualBlockNumber = currentBlockNumber;\n borrowIndex = borrowIndexNew;\n totalBorrows = totalBorrowsNew;\n totalReserves = totalReservesNew;\n\n /* We emit an AccrueInterest event */\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\n\n return uint(Error.NO_ERROR);\n }\n}\n" + }, + "contracts/test/SimplePriceOracle.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Tokens/VTokens/VBep20.sol\";\n\ncontract SimplePriceOracle is PriceOracle {\n mapping(address => uint) internal prices;\n event PricePosted(address asset, uint previousPriceMantissa, uint requestedPriceMantissa, uint newPriceMantissa);\n\n function getUnderlyingPrice(VToken vToken) public view returns (uint) {\n if (compareStrings(vToken.symbol(), \"vBNB\")) {\n return 1e18;\n } else if (compareStrings(vToken.symbol(), \"VAI\")) {\n return prices[address(vToken)];\n } else {\n return prices[address(VBep20(address(vToken)).underlying())];\n }\n }\n\n function setUnderlyingPrice(VToken vToken, uint underlyingPriceMantissa) public {\n address asset = address(VBep20(address(vToken)).underlying());\n emit PricePosted(asset, prices[asset], underlyingPriceMantissa, underlyingPriceMantissa);\n prices[asset] = underlyingPriceMantissa;\n }\n\n function setDirectPrice(address asset, uint price) public {\n emit PricePosted(asset, prices[asset], price, price);\n prices[asset] = price;\n }\n\n // v1 price oracle interface for use as backing of proxy\n function assetPrices(address asset) external view returns (uint) {\n return prices[asset];\n }\n\n function compareStrings(string memory a, string memory b) internal pure returns (bool) {\n return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));\n }\n}\n" + }, + "contracts/test/VAIControllerHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VAI/VAIController.sol\";\n\ncontract VAIControllerHarness is VAIController {\n uint public blockNumber;\n uint public blocksPerYear;\n\n constructor() public VAIController() {\n admin = msg.sender;\n }\n\n function setVenusVAIState(uint224 index, uint32 blockNumber_) public {\n venusVAIState.index = index;\n venusVAIState.block = blockNumber_;\n }\n\n function setVAIAddress(address vaiAddress_) public {\n vai = vaiAddress_;\n }\n\n function getVAIAddress() public view returns (address) {\n return vai;\n }\n\n function harnessRepayVAIFresh(address payer, address account, uint repayAmount) public returns (uint) {\n (uint err, ) = repayVAIFresh(payer, account, repayAmount);\n return err;\n }\n\n function harnessLiquidateVAIFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VToken vTokenCollateral\n ) public returns (uint) {\n (uint err, ) = liquidateVAIFresh(liquidator, borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n function harnessFastForward(uint blocks) public returns (uint) {\n blockNumber += blocks;\n return blockNumber;\n }\n\n function harnessSetBlockNumber(uint newBlockNumber) public {\n blockNumber = newBlockNumber;\n }\n\n function setBlockNumber(uint number) public {\n blockNumber = number;\n }\n\n function setBlocksPerYear(uint number) public {\n blocksPerYear = number;\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getBlocksPerYear() public view returns (uint) {\n return blocksPerYear;\n }\n}\n" + }, + "contracts/test/VAIHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VAI/VAI.sol\";\n\ncontract VAIScenario is VAI {\n uint internal blockNumber = 100000;\n\n constructor(uint chainId) public VAI(chainId) {}\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n function harnessSetTotalSupply(uint _totalSupply) public {\n totalSupply = _totalSupply;\n }\n\n function harnessIncrementTotalSupply(uint addtlSupply_) public {\n totalSupply = totalSupply + addtlSupply_;\n }\n\n function harnessSetBalanceOf(address account, uint _amount) public {\n balanceOf[account] = _amount;\n }\n\n function allocateTo(address _owner, uint256 value) public {\n balanceOf[_owner] += value;\n totalSupply += value;\n emit Transfer(address(this), _owner, value);\n }\n}\n" + }, + "contracts/test/VBep20Harness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VBep20Immutable.sol\";\nimport \"../Tokens/VTokens/VBep20Delegator.sol\";\nimport \"../Tokens/VTokens/VBep20Delegate.sol\";\nimport \"./ComptrollerScenario.sol\";\n\ncontract VBep20Harness is VBep20Immutable {\n uint internal blockNumber = 100000;\n uint internal harnessExchangeRate;\n bool internal harnessExchangeRateStored;\n\n mapping(address => bool) public failTransferToAddresses;\n\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n )\n public\n VBep20Immutable(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_\n )\n {}\n\n function doTransferOut(address payable to, uint amount) internal {\n require(failTransferToAddresses[to] == false, \"TOKEN_TRANSFER_OUT_FAILED\");\n return super.doTransferOut(to, amount);\n }\n\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\n if (harnessExchangeRateStored) {\n return (MathError.NO_ERROR, harnessExchangeRate);\n }\n return super.exchangeRateStoredInternal();\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getBorrowRateMaxMantissa() public pure returns (uint) {\n return borrowRateMaxMantissa;\n }\n\n function harnessSetAccrualBlockNumber(uint _accrualblockNumber) public {\n accrualBlockNumber = _accrualblockNumber;\n }\n\n function harnessSetBlockNumber(uint newBlockNumber) public {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetTotalSupply(uint totalSupply_) public {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function harnessSetTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(uint totalSupply_, uint totalBorrows_, uint totalReserves_) public {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint exchangeRate) public {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address _to, bool _fail) public {\n failTransferToAddresses[_to] = _fail;\n }\n\n function harnessMintFresh(address account, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintFresh(account, mintAmount);\n return err;\n }\n\n function harnessMintBehalfFresh(address payer, address receiver, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintBehalfFresh(payer, receiver, mintAmount);\n return err;\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint vTokenAmount,\n uint underlyingAmount\n ) public returns (uint) {\n return super.redeemFresh(account, account, vTokenAmount, underlyingAmount);\n }\n\n function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function harnessSetAccountBorrows(address account, uint principal, uint interestIndex) public {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint borrowIndex_) public {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint borrowAmount) public returns (uint) {\n return borrowFresh(account, account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(address payer, address account, uint repayAmount) public returns (uint) {\n (uint err, ) = repayBorrowFresh(payer, account, repayAmount);\n return err;\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VToken vTokenCollateral\n ) public returns (uint) {\n (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n function harnessReduceReservesFresh(uint amount) public returns (uint) {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint newReserveFactorMantissa) public returns (uint) {\n return _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) public returns (uint) {\n return _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallBorrowAllowed(uint amount) public returns (uint) {\n return comptroller.borrowAllowed(address(this), msg.sender, amount);\n }\n}\n\ncontract VBep20Scenario is VBep20Immutable {\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n )\n public\n VBep20Immutable(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_\n )\n {}\n\n function setTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function setTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function getBlockNumber() internal view returns (uint) {\n ComptrollerScenario comptrollerScenario = ComptrollerScenario(address(comptroller));\n return comptrollerScenario.blockNumber();\n }\n}\n\ncontract VEvil is VBep20Scenario {\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n )\n public\n VBep20Scenario(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_\n )\n {}\n\n function evilSeize(VToken treasure, address liquidator, address borrower, uint seizeTokens) public returns (uint) {\n return treasure.seize(liquidator, borrower, seizeTokens);\n }\n}\n\ncontract VBep20DelegatorScenario is VBep20Delegator {\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_,\n address implementation_,\n bytes memory becomeImplementationData\n )\n public\n VBep20Delegator(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_,\n implementation_,\n becomeImplementationData\n )\n {}\n\n function setTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function setTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n}\n\ncontract VBep20DelegateHarness is VBep20Delegate {\n event Log(string x, address y);\n event Log(string x, uint y);\n\n uint internal blockNumber = 100000;\n uint internal harnessExchangeRate;\n bool internal harnessExchangeRateStored;\n\n mapping(address => bool) public failTransferToAddresses;\n\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\n if (harnessExchangeRateStored) {\n return (MathError.NO_ERROR, harnessExchangeRate);\n }\n return super.exchangeRateStoredInternal();\n }\n\n function doTransferOut(address payable to, uint amount) internal {\n require(failTransferToAddresses[to] == false, \"TOKEN_TRANSFER_OUT_FAILED\");\n return super.doTransferOut(to, amount);\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getBorrowRateMaxMantissa() public pure returns (uint) {\n return borrowRateMaxMantissa;\n }\n\n function harnessSetBlockNumber(uint newBlockNumber) public {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetAccrualBlockNumber(uint _accrualblockNumber) public {\n accrualBlockNumber = _accrualblockNumber;\n }\n\n function harnessSetTotalSupply(uint totalSupply_) public {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function harnessIncrementTotalBorrows(uint addtlBorrow_) public {\n totalBorrows = totalBorrows + addtlBorrow_;\n }\n\n function harnessSetTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(uint totalSupply_, uint totalBorrows_, uint totalReserves_) public {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint exchangeRate) public {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address _to, bool _fail) public {\n failTransferToAddresses[_to] = _fail;\n }\n\n function harnessMintFresh(address account, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintFresh(account, mintAmount);\n return err;\n }\n\n function harnessMintBehalfFresh(address payer, address receiver, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintBehalfFresh(payer, receiver, mintAmount);\n return err;\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint vTokenAmount,\n uint underlyingAmount\n ) public returns (uint) {\n return super.redeemFresh(account, account, vTokenAmount, underlyingAmount);\n }\n\n function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function harnessSetAccountBorrows(address account, uint principal, uint interestIndex) public {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint borrowIndex_) public {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint borrowAmount) public returns (uint) {\n return borrowFresh(account, account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(address payer, address account, uint repayAmount) public returns (uint) {\n (uint err, ) = repayBorrowFresh(payer, account, repayAmount);\n return err;\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VToken vTokenCollateral\n ) public returns (uint) {\n (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n function harnessReduceReservesFresh(uint amount) public returns (uint) {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint newReserveFactorMantissa) public returns (uint) {\n return _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) public returns (uint) {\n return _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallBorrowAllowed(uint amount) public returns (uint) {\n return comptroller.borrowAllowed(address(this), msg.sender, amount);\n }\n}\n\ncontract VBep20DelegateScenario is VBep20Delegate {\n constructor() public {}\n\n function setTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function setTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function getBlockNumber() internal view returns (uint) {\n ComptrollerScenario comptrollerScenario = ComptrollerScenario(address(comptroller));\n return comptrollerScenario.blockNumber();\n }\n}\n\ncontract VBep20DelegateScenarioExtra is VBep20DelegateScenario {\n function iHaveSpoken() public pure returns (string memory) {\n return \"i have spoken\";\n }\n\n function itIsTheWay() public {\n admin = address(1); // make a change to test effect\n }\n\n function babyYoda() public pure {\n revert(\"protect the baby\");\n }\n}\n" + }, + "contracts/test/VBep20MockDelegate.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VToken.sol\";\n\n/**\n * @title Venus's VBep20 Contract\n * @notice VTokens which wrap an EIP-20 underlying\n * @author Venus\n */\ncontract VBep20MockDelegate is VToken, VBep20Interface {\n address public implementation;\n uint internal blockNumber = 100000;\n\n /**\n * @notice Initialize the new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n */\n function initialize(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) public {\n // VToken initialize does the bulk of the work\n super.initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_);\n\n // Set underlying and sanity check it\n underlying = underlying_;\n EIP20Interface(underlying).totalSupply();\n }\n\n /**\n * @notice Called by the delegator on a delegate to initialize it for duty\n * @param data The encoded bytes data for any initialization\n */\n function _becomeImplementation(bytes memory data) public {\n // Shh -- currently unused\n data;\n\n // Shh -- we don't ever want this hook to be marked pure\n if (false) {\n implementation = address(0);\n }\n\n require(msg.sender == admin, \"only the admin may call _becomeImplementation\");\n }\n\n /**\n * @notice Called by the delegator on a delegate to forfeit its responsibility\n */\n function _resignImplementation() public {\n // Shh -- we don't ever want this hook to be marked pure\n if (false) {\n implementation = address(0);\n }\n\n require(msg.sender == admin, \"only the admin may call _resignImplementation\");\n }\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n /*** User Interface ***/\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function mint(uint mintAmount) external returns (uint) {\n (uint err, ) = mintInternal(mintAmount);\n return err;\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param receiver the account which is receiving the vTokens\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function mintBehalf(address receiver, uint mintAmount) external returns (uint) {\n (uint err, ) = mintBehalfInternal(receiver, mintAmount);\n return err;\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function redeem(uint redeemTokens) external returns (uint) {\n return redeemInternal(msg.sender, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n return redeemUnderlyingInternal(msg.sender, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function borrow(uint borrowAmount) external returns (uint) {\n return borrowInternal(msg.sender, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function repayBorrow(uint repayAmount) external returns (uint) {\n (uint err, ) = repayBorrowInternal(repayAmount);\n return err;\n }\n\n /**\n * @notice Sender repays a borrow belonging to borrower\n * @param borrower the account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) {\n (uint err, ) = repayBorrowBehalfInternal(borrower, repayAmount);\n return err;\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function liquidateBorrow(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint) {\n (uint err, ) = liquidateBorrowInternal(borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n /**\n * @notice The sender adds to reserves.\n * @param addAmount The amount fo underlying token to add as reserves\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _addReserves(uint addAmount) external returns (uint) {\n return _addReservesInternal(addAmount);\n }\n\n /*** Safe Token ***/\n\n /**\n * @notice Gets balance of this contract in terms of the underlying\n * @dev This excludes the value of the current message, if any\n * @return The quantity of underlying tokens owned by this contract\n */\n function getCashPrior() internal view returns (uint) {\n EIP20Interface token = EIP20Interface(underlying);\n return token.balanceOf(address(this));\n }\n\n /**\n * @dev Similar to EIP20 transfer, except it handles a False result from `transferFrom` and reverts in that case.\n * This will revert due to insufficient balance or insufficient allowance.\n * This function returns the actual amount received,\n * which may be less than `amount` if there is a fee attached to the transfer.\n *\n * Note: This wrapper safely handles non-standard BEP-20 tokens that do not return a value.\n * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\n function doTransferIn(address from, uint amount) internal returns (uint) {\n EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying);\n uint balanceBefore = EIP20Interface(underlying).balanceOf(address(this));\n token.transferFrom(from, address(this), amount);\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a compliant BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n require(success, \"TOKEN_TRANSFER_IN_FAILED\");\n\n // Calculate the amount that was *actually* transferred\n uint balanceAfter = EIP20Interface(underlying).balanceOf(address(this));\n require(balanceAfter >= balanceBefore, \"TOKEN_TRANSFER_IN_OVERFLOW\");\n return balanceAfter - balanceBefore; // underflow already checked above, just subtract\n }\n\n /**\n * @dev Similar to EIP20 transfer, except it handles a False success from `transfer` and returns an explanatory\n * error code rather than reverting. If caller has not called checked protocol's balance, this may revert due to\n * insufficient cash held in this contract. If caller has checked protocol's balance prior to this call, and verified\n * it is >= amount, this should not revert in normal conditions.\n *\n * Note: This wrapper safely handles non-standard BEP-20 tokens that do not return a value.\n * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\n function doTransferOut(address payable to, uint amount) internal {\n EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying);\n token.transfer(to, amount);\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a complaint BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n require(success, \"TOKEN_TRANSFER_OUT_FAILED\");\n }\n}\n" + }, + "contracts/test/VRTConverterHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../contracts/Tokens/VRT/VRTConverter.sol\";\n\ncontract VRTConverterHarness is VRTConverter {\n constructor() public VRTConverter() {\n admin = msg.sender;\n }\n\n function balanceOfUser() public view returns (uint256, address) {\n uint256 vrtBalanceOfUser = vrt.balanceOf(msg.sender);\n return (vrtBalanceOfUser, msg.sender);\n }\n\n function setConversionRatio(uint256 _conversionRatio) public onlyAdmin {\n conversionRatio = _conversionRatio;\n }\n\n function setConversionTimeline(uint256 _conversionStartTime, uint256 _conversionPeriod) public onlyAdmin {\n conversionStartTime = _conversionStartTime;\n conversionPeriod = _conversionPeriod;\n conversionEndTime = conversionStartTime.add(conversionPeriod);\n }\n\n function getXVSRedeemedAmount(uint256 vrtAmount) public view returns (uint256) {\n return vrtAmount.mul(conversionRatio).mul(xvsDecimalsMultiplier).div(1e18).div(vrtDecimalsMultiplier);\n }\n}\n" + }, + "contracts/test/VRTVaultHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../contracts/VRTVault/VRTVault.sol\";\n\ncontract VRTVaultHarness is VRTVault {\n uint public blockNumber;\n\n constructor() public VRTVault() {}\n\n function overrideInterestRatePerBlock(uint256 _interestRatePerBlock) public {\n interestRatePerBlock = _interestRatePerBlock;\n }\n\n function balanceOfUser() public view returns (uint256, address) {\n uint256 vrtBalanceOfUser = vrt.balanceOf(msg.sender);\n return (vrtBalanceOfUser, msg.sender);\n }\n\n function harnessFastForward(uint256 blocks) public returns (uint256) {\n blockNumber += blocks;\n return blockNumber;\n }\n\n function setBlockNumber(uint256 number) public {\n blockNumber = number;\n }\n\n function getBlockNumber() public view returns (uint256) {\n return blockNumber;\n }\n}\n" + }, + "contracts/test/XVSHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/XVS/XVS.sol\";\n\ncontract XVSScenario is XVS {\n constructor(address account) public XVS(account) {}\n\n function transferScenario(address[] calldata destinations, uint256 amount) external returns (bool) {\n for (uint i = 0; i < destinations.length; i++) {\n address dst = destinations[i];\n _transferTokens(msg.sender, dst, uint96(amount));\n }\n return true;\n }\n\n function transferFromScenario(address[] calldata froms, uint256 amount) external returns (bool) {\n for (uint i = 0; i < froms.length; i++) {\n address from = froms[i];\n _transferTokens(from, msg.sender, uint96(amount));\n }\n return true;\n }\n\n function generateCheckpoints(uint count, uint offset) external {\n for (uint i = 1 + offset; i <= count + offset; i++) {\n checkpoints[msg.sender][numCheckpoints[msg.sender]++] = Checkpoint(uint32(i), uint96(i));\n }\n }\n}\n" + }, + "contracts/test/XVSVaultScenario.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../XVSVault/XVSVault.sol\";\n\ncontract XVSVaultScenario is XVSVault {\n using SafeMath for uint256;\n\n constructor() public {\n admin = msg.sender;\n }\n\n function pushOldWithdrawalRequest(\n UserInfo storage _user,\n WithdrawalRequest[] storage _requests,\n uint _amount,\n uint _lockedUntil\n ) internal {\n uint i = _requests.length;\n _requests.push(WithdrawalRequest(0, 0, 0));\n // Keep it sorted so that the first to get unlocked request is always at the end\n for (; i > 0 && _requests[i - 1].lockedUntil <= _lockedUntil; --i) {\n _requests[i] = _requests[i - 1];\n }\n _requests[i] = WithdrawalRequest(_amount, uint128(_lockedUntil), 0);\n _user.pendingWithdrawals = _user.pendingWithdrawals.add(_amount);\n }\n\n function requestOldWithdrawal(address _rewardToken, uint256 _pid, uint256 _amount) external nonReentrant {\n _ensureValidPool(_rewardToken, _pid);\n require(_amount > 0, \"requested amount cannot be zero\");\n UserInfo storage user = userInfos[_rewardToken][_pid][msg.sender];\n require(user.amount >= user.pendingWithdrawals.add(_amount), \"requested amount is invalid\");\n\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][msg.sender];\n uint lockedUntil = pool.lockPeriod.add(block.timestamp);\n\n pushOldWithdrawalRequest(user, requests, _amount, lockedUntil);\n\n // Update Delegate Amount\n if (_rewardToken == address(xvsAddress)) {\n _moveDelegates(delegates[msg.sender], address(0), uint96(_amount));\n }\n\n emit RequestedWithdrawal(msg.sender, _rewardToken, _pid, _amount);\n }\n\n function transferReward(address rewardToken, address user, uint256 amount) external {\n _transferReward(rewardToken, user, amount);\n }\n}\n" + }, + "contracts/test/XVSVestingHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../contracts/Tokens/XVS/XVSVesting.sol\";\n\ncontract XVSVestingHarness is XVSVesting {\n address public constant ZERO_ADDRESS = 0x0000000000000000000000000000000000000000;\n\n constructor() public XVSVesting() {\n admin = msg.sender;\n }\n\n uint public blockNumber;\n\n function recoverXVS(address recoveryAddress) public payable {\n uint256 xvsBalance = xvs.balanceOf(address(this));\n xvs.safeTransferFrom(address(this), recoveryAddress, xvsBalance);\n }\n\n function overWriteVRTConversionAddress() public {\n vrtConversionAddress = ZERO_ADDRESS;\n }\n\n function computeWithdrawableAmount(\n uint256 amount,\n uint256 vestingStartTime,\n uint256 withdrawnAmount\n ) public view returns (uint256 vestedAmount, uint256 toWithdraw) {\n (vestedAmount, toWithdraw) = super.calculateWithdrawableAmount(amount, vestingStartTime, withdrawnAmount);\n return (vestedAmount, toWithdraw);\n }\n\n function computeVestedAmount(\n uint256 vestingAmount,\n uint256 vestingStartTime,\n uint256 currentTime\n ) public view returns (uint256) {\n return super.calculateVestedAmount(vestingAmount, vestingStartTime, currentTime);\n }\n\n function getVestingCount(address beneficiary) public view returns (uint256) {\n return vestings[beneficiary].length;\n }\n\n function getVestedAmount(address recipient) public view nonZeroAddress(recipient) returns (uint256) {\n VestingRecord[] memory vestingsOfRecipient = vestings[recipient];\n uint256 vestingCount = vestingsOfRecipient.length;\n uint256 totalVestedAmount = 0;\n uint256 currentTime = getCurrentTime();\n\n for (uint i = 0; i < vestingCount; i++) {\n VestingRecord memory vesting = vestingsOfRecipient[i];\n uint256 vestedAmount = calculateVestedAmount(vesting.amount, vesting.startTime, currentTime);\n totalVestedAmount = totalVestedAmount.add(vestedAmount);\n }\n\n return totalVestedAmount;\n }\n}\n" + }, + "contracts/Tokens/EIP20Interface.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title BEP 20 Token Standard Interface\n * https://eips.ethereum.org/EIPS/eip-20\n */\ninterface EIP20Interface {\n function name() external view returns (string memory);\n\n function symbol() external view returns (string memory);\n\n function decimals() external view returns (uint8);\n\n /**\n * @notice Get the total number of tokens in circulation\n * @return The supply of tokens\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @notice Gets the balance of the specified address\n * @param owner The address from which the balance will be retrieved\n * @return balance\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return success whether or not the transfer succeeded\n */\n function transfer(address dst, uint256 amount) external returns (bool success);\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return success whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved (-1 means infinite)\n * @return success whether or not the approval succeeded\n */\n function approve(address spender, uint256 amount) external returns (bool success);\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return remaining The number of tokens allowed to be spent\n */\n function allowance(address owner, address spender) external view returns (uint256 remaining);\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n}\n" + }, + "contracts/Tokens/EIP20NonStandardInterface.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title EIP20NonStandardInterface\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\ninterface EIP20NonStandardInterface {\n /**\n * @notice Get the total number of tokens in circulation\n * @return The supply of tokens\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @notice Gets the balance of the specified address\n * @param owner The address from which the balance will be retrieved\n * @return balance of the owner\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n ///\n /// !!!!!!!!!!!!!!\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\n /// !!!!!!!!!!!!!!\n ///\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n */\n function transfer(address dst, uint256 amount) external;\n\n ///\n /// !!!!!!!!!!!!!!\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\n /// !!!!!!!!!!!!!!\n ///\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n */\n function transferFrom(address src, address dst, uint256 amount) external;\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved\n * @return success Whether or not the approval succeeded\n */\n function approve(address spender, uint256 amount) external returns (bool success);\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return remaining The number of tokens allowed to be spent\n */\n function allowance(address owner, address spender) external view returns (uint256 remaining);\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n}\n" + }, + "contracts/Tokens/Prime/IPrime.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\n/**\n * @title IPrime\n * @author Venus\n * @notice Interface for Prime Token\n */\ninterface IPrime {\n /**\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\n * @param user the account address whose balance was updated\n */\n function xvsUpdated(address user) external;\n\n /**\n * @notice accrues interest and updates score for an user for a specific market\n * @param user the account address for which to accrue interest and update score\n * @param market the market for which to accrue interest and update score\n */\n function accrueInterestAndUpdateScore(address user, address market) external;\n\n /**\n * @notice Distributes income from market since last distribution\n * @param vToken the market for which to distribute the income\n */\n function accrueInterest(address vToken) external;\n\n /**\n * @notice Returns if user is a prime holder\n * @param isPrimeHolder returns if the user is a prime holder\n */\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\n}\n" + }, + "contracts/Tokens/VAI/lib.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity ^0.5.16;\n\ncontract LibNote {\n event LogNote(\n bytes4 indexed sig,\n address indexed usr,\n bytes32 indexed arg1,\n bytes32 indexed arg2,\n bytes data\n ) anonymous;\n\n modifier note() {\n _;\n assembly {\n // log an 'anonymous' event with a constant 6 words of calldata\n // and four indexed topics: selector, caller, arg1 and arg2\n let mark := msize() // end of memory ensures zero\n mstore(0x40, add(mark, 288)) // update free memory pointer\n mstore(mark, 0x20) // bytes type data offset\n mstore(add(mark, 0x20), 224) // bytes size (padded)\n calldatacopy(add(mark, 0x40), 0, 224) // bytes payload\n log4(\n mark,\n 288, // calldata\n shl(224, shr(224, calldataload(0))), // msg.sig\n caller(), // msg.sender\n calldataload(4), // arg1\n calldataload(36) // arg2\n )\n }\n }\n}\n" + }, + "contracts/Tokens/VAI/VAI.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\n\n// Copyright (C) 2017, 2018, 2019 dbrock, rain, mrchico\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity ^0.5.16;\n\nimport \"./lib.sol\";\n\ncontract VAI is LibNote {\n // --- Auth ---\n mapping(address => uint256) public wards;\n\n function rely(address guy) external note auth {\n wards[guy] = 1;\n }\n\n function deny(address guy) external note auth {\n wards[guy] = 0;\n }\n\n modifier auth() {\n require(wards[msg.sender] == 1, \"VAI/not-authorized\");\n _;\n }\n\n // --- BEP20 Data ---\n string public constant name = \"VAI Stablecoin\";\n string public constant symbol = \"VAI\";\n string public constant version = \"1\";\n uint8 public constant decimals = 18;\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n mapping(address => mapping(address => uint256)) public allowance;\n mapping(address => uint256) public nonces;\n\n event Approval(address indexed src, address indexed guy, uint256 wad);\n event Transfer(address indexed src, address indexed dst, uint256 wad);\n\n // --- Math ---\n function add(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require((z = x + y) >= x, \"VAI math error\");\n }\n\n function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require((z = x - y) <= x, \"VAI math error\");\n }\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n constructor(uint256 chainId_) public {\n wards[msg.sender] = 1;\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n // --- Token ---\n function transfer(address dst, uint256 wad) external returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint256 wad) public returns (bool) {\n require(balanceOf[src] >= wad, \"VAI/insufficient-balance\");\n if (src != msg.sender && allowance[src][msg.sender] != uint256(-1)) {\n require(allowance[src][msg.sender] >= wad, \"VAI/insufficient-allowance\");\n allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);\n }\n balanceOf[src] = sub(balanceOf[src], wad);\n balanceOf[dst] = add(balanceOf[dst], wad);\n emit Transfer(src, dst, wad);\n return true;\n }\n\n function mint(address usr, uint256 wad) external auth {\n balanceOf[usr] = add(balanceOf[usr], wad);\n totalSupply = add(totalSupply, wad);\n emit Transfer(address(0), usr, wad);\n }\n\n function burn(address usr, uint256 wad) external {\n require(balanceOf[usr] >= wad, \"VAI/insufficient-balance\");\n if (usr != msg.sender && allowance[usr][msg.sender] != uint256(-1)) {\n require(allowance[usr][msg.sender] >= wad, \"VAI/insufficient-allowance\");\n allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad);\n }\n balanceOf[usr] = sub(balanceOf[usr], wad);\n totalSupply = sub(totalSupply, wad);\n emit Transfer(usr, address(0), wad);\n }\n\n function approve(address usr, uint256 wad) external returns (bool) {\n allowance[msg.sender][usr] = wad;\n emit Approval(msg.sender, usr, wad);\n return true;\n }\n\n // --- Alias ---\n function push(address usr, uint256 wad) external {\n transferFrom(msg.sender, usr, wad);\n }\n\n function pull(address usr, uint256 wad) external {\n transferFrom(usr, msg.sender, wad);\n }\n\n function move(address src, address dst, uint256 wad) external {\n transferFrom(src, dst, wad);\n }\n\n // --- Approve by signature ---\n function permit(\n address holder,\n address spender,\n uint256 nonce,\n uint256 expiry,\n bool allowed,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(abi.encode(PERMIT_TYPEHASH, holder, spender, nonce, expiry, allowed))\n )\n );\n\n require(holder != address(0), \"VAI/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"VAI/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"VAI/permit-expired\");\n require(nonce == nonces[holder]++, \"VAI/invalid-nonce\");\n uint256 wad = allowed ? uint256(-1) : 0;\n allowance[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n}\n" + }, + "contracts/Tokens/VAI/VAIController.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.5.16;\n\nimport { PriceOracle } from \"../../Oracle/PriceOracle.sol\";\nimport { VAIControllerErrorReporter } from \"../../Utils/ErrorReporter.sol\";\nimport { Exponential } from \"../../Utils/Exponential.sol\";\nimport { ComptrollerInterface } from \"../../Comptroller/ComptrollerInterface.sol\";\nimport { IAccessControlManagerV5 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\";\nimport { VToken, EIP20Interface } from \"../VTokens/VToken.sol\";\nimport { VAIUnitroller, VAIControllerStorageG4 } from \"./VAIUnitroller.sol\";\nimport { VAIControllerInterface } from \"./VAIControllerInterface.sol\";\nimport { VAI } from \"./VAI.sol\";\nimport { IPrime } from \"../Prime/IPrime.sol\";\nimport { VTokenInterface } from \"../VTokens/VTokenInterfaces.sol\";\n\n/**\n * @title VAI Comptroller\n * @author Venus\n * @notice This is the implementation contract for the VAIUnitroller proxy\n */\ncontract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAIControllerErrorReporter, Exponential {\n /// @notice Initial index used in interest computations\n uint256 public constant INITIAL_VAI_MINT_INDEX = 1e18;\n\n /// @notice Emitted when Comptroller is changed\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\n\n /// @notice Emitted when mint for prime holder is changed\n event MintOnlyForPrimeHolder(bool previousMintEnabledOnlyForPrimeHolder, bool newMintEnabledOnlyForPrimeHolder);\n\n /// @notice Emitted when Prime is changed\n event NewPrime(address oldPrime, address newPrime);\n\n /// @notice Event emitted when VAI is minted\n event MintVAI(address minter, uint256 mintVAIAmount);\n\n /// @notice Event emitted when VAI is repaid\n event RepayVAI(address payer, address borrower, uint256 repayVAIAmount);\n\n /// @notice Event emitted when a borrow is liquidated\n event LiquidateVAI(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n address vTokenCollateral,\n uint256 seizeTokens\n );\n\n /// @notice Emitted when treasury guardian is changed\n event NewTreasuryGuardian(address oldTreasuryGuardian, address newTreasuryGuardian);\n\n /// @notice Emitted when treasury address is changed\n event NewTreasuryAddress(address oldTreasuryAddress, address newTreasuryAddress);\n\n /// @notice Emitted when treasury percent is changed\n event NewTreasuryPercent(uint256 oldTreasuryPercent, uint256 newTreasuryPercent);\n\n /// @notice Event emitted when VAIs are minted and fee are transferred\n event MintFee(address minter, uint256 feeAmount);\n\n /// @notice Emiitted when VAI base rate is changed\n event NewVAIBaseRate(uint256 oldBaseRateMantissa, uint256 newBaseRateMantissa);\n\n /// @notice Emiitted when VAI float rate is changed\n event NewVAIFloatRate(uint256 oldFloatRateMantissa, uint256 newFlatRateMantissa);\n\n /// @notice Emiitted when VAI receiver address is changed\n event NewVAIReceiver(address oldReceiver, address newReceiver);\n\n /// @notice Emiitted when VAI mint cap is changed\n event NewVAIMintCap(uint256 oldMintCap, uint256 newMintCap);\n\n /// @notice Emitted when access control address is changed by admin\n event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress);\n\n /// @notice Emitted when VAI token address is changed by admin\n event NewVaiToken(address oldVaiToken, address newVaiToken);\n\n function initialize() external onlyAdmin {\n require(vaiMintIndex == 0, \"already initialized\");\n\n vaiMintIndex = INITIAL_VAI_MINT_INDEX;\n accrualBlockNumber = getBlockNumber();\n mintCap = uint256(-1);\n\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\n _notEntered = true;\n }\n\n function _become(VAIUnitroller unitroller) external {\n require(msg.sender == unitroller.admin(), \"only unitroller admin can change brains\");\n require(unitroller._acceptImplementation() == 0, \"change not authorized\");\n }\n\n /**\n * @notice The mintVAI function mints and transfers VAI from the protocol to the user, and adds a borrow balance.\n * The amount minted must be less than the user's Account Liquidity and the mint vai limit.\n * @dev If the Comptroller address is not set, minting is a no-op and the function returns the success code.\n * @param mintVAIAmount The amount of the VAI to be minted.\n * @return 0 on success, otherwise an error code\n */\n // solhint-disable-next-line code-complexity\n function mintVAI(uint256 mintVAIAmount) external nonReentrant returns (uint256) {\n if (address(comptroller) == address(0)) {\n return uint256(Error.NO_ERROR);\n }\n\n _ensureNonzeroAmount(mintVAIAmount);\n _ensureNotPaused();\n accrueVAIInterest();\n\n uint256 err;\n address minter = msg.sender;\n address _vai = vai;\n uint256 vaiTotalSupply = EIP20Interface(_vai).totalSupply();\n\n uint256 vaiNewTotalSupply = add_(vaiTotalSupply, mintVAIAmount);\n require(vaiNewTotalSupply <= mintCap, \"mint cap reached\");\n\n uint256 accountMintableVAI;\n (err, accountMintableVAI) = getMintableVAI(minter);\n require(err == uint256(Error.NO_ERROR), \"could not compute mintable amount\");\n\n // check that user have sufficient mintableVAI balance\n require(mintVAIAmount <= accountMintableVAI, \"minting more than allowed\");\n\n // Calculate the minted balance based on interest index\n uint256 totalMintedVAI = comptroller.mintedVAIs(minter);\n\n if (totalMintedVAI > 0) {\n uint256 repayAmount = getVAIRepayAmount(minter);\n uint256 remainedAmount = sub_(repayAmount, totalMintedVAI);\n pastVAIInterest[minter] = add_(pastVAIInterest[minter], remainedAmount);\n totalMintedVAI = repayAmount;\n }\n\n uint256 accountMintVAINew = add_(totalMintedVAI, mintVAIAmount);\n err = comptroller.setMintedVAIOf(minter, accountMintVAINew);\n require(err == uint256(Error.NO_ERROR), \"comptroller rejection\");\n\n uint256 remainedAmount;\n if (treasuryPercent != 0) {\n uint256 feeAmount = div_(mul_(mintVAIAmount, treasuryPercent), 1e18);\n remainedAmount = sub_(mintVAIAmount, feeAmount);\n VAI(_vai).mint(treasuryAddress, feeAmount);\n\n emit MintFee(minter, feeAmount);\n } else {\n remainedAmount = mintVAIAmount;\n }\n\n VAI(_vai).mint(minter, remainedAmount);\n vaiMinterInterestIndex[minter] = vaiMintIndex;\n\n emit MintVAI(minter, remainedAmount);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice The repay function transfers VAI interest into the protocol and burns the rest,\n * reducing the borrower's borrow balance. Before repaying VAI, users must first approve\n * VAIController to access their VAI balance.\n * @dev If the Comptroller address is not set, repayment is a no-op and the function returns the success code.\n * @param amount The amount of VAI to be repaid.\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function repayVAI(uint256 amount) external nonReentrant returns (uint256, uint256) {\n return _repayVAI(msg.sender, amount);\n }\n\n /**\n * @notice The repay on behalf function transfers VAI interest into the protocol and burns the rest,\n * reducing the borrower's borrow balance. Borrowed VAIs are repaid by another user (possibly the borrower).\n * Before repaying VAI, the payer must first approve VAIController to access their VAI balance.\n * @dev If the Comptroller address is not set, repayment is a no-op and the function returns the success code.\n * @param borrower The account to repay the debt for.\n * @param amount The amount of VAI to be repaid.\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function repayVAIBehalf(address borrower, uint256 amount) external nonReentrant returns (uint256, uint256) {\n _ensureNonzeroAddress(borrower);\n return _repayVAI(borrower, amount);\n }\n\n /**\n * @dev Checks the parameters and the protocol state, accrues interest, and invokes repayVAIFresh.\n * @dev If the Comptroller address is not set, repayment is a no-op and the function returns the success code.\n * @param borrower The account to repay the debt for.\n * @param amount The amount of VAI to be repaid.\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function _repayVAI(address borrower, uint256 amount) internal returns (uint256, uint256) {\n if (address(comptroller) == address(0)) {\n return (0, 0);\n }\n _ensureNonzeroAmount(amount);\n _ensureNotPaused();\n\n accrueVAIInterest();\n return repayVAIFresh(msg.sender, borrower, amount);\n }\n\n /**\n * @dev Repay VAI, expecting interest to be accrued\n * @dev Borrowed VAIs are repaid by another user (possibly the borrower).\n * @param payer the account paying off the VAI\n * @param borrower the account with the debt being payed off\n * @param repayAmount the amount of VAI being repaid\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function repayVAIFresh(address payer, address borrower, uint256 repayAmount) internal returns (uint256, uint256) {\n (uint256 burn, uint256 partOfCurrentInterest, uint256 partOfPastInterest) = getVAICalculateRepayAmount(\n borrower,\n repayAmount\n );\n\n VAI _vai = VAI(vai);\n _vai.burn(payer, burn);\n bool success = _vai.transferFrom(payer, receiver, partOfCurrentInterest);\n require(success == true, \"failed to transfer VAI fee\");\n\n uint256 vaiBalanceBorrower = comptroller.mintedVAIs(borrower);\n\n uint256 accountVAINew = sub_(sub_(vaiBalanceBorrower, burn), partOfPastInterest);\n pastVAIInterest[borrower] = sub_(pastVAIInterest[borrower], partOfPastInterest);\n\n uint256 error = comptroller.setMintedVAIOf(borrower, accountVAINew);\n // We have to revert upon error since side-effects already happened at this point\n require(error == uint256(Error.NO_ERROR), \"comptroller rejection\");\n\n uint256 repaidAmount = add_(burn, partOfCurrentInterest);\n emit RepayVAI(payer, borrower, repaidAmount);\n\n return (uint256(Error.NO_ERROR), repaidAmount);\n }\n\n /**\n * @notice The sender liquidates the vai minters collateral. The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of vai to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function liquidateVAI(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external nonReentrant returns (uint256, uint256) {\n _ensureNotPaused();\n\n uint256 error = vTokenCollateral.accrueInterest();\n if (error != uint256(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n return (fail(Error(error), FailureInfo.VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\n }\n\n // liquidateVAIFresh emits borrow-specific logs on errors, so we don't need to\n return liquidateVAIFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\n }\n\n /**\n * @notice The liquidator liquidates the borrowers collateral by repay borrowers VAI.\n * The collateral seized is transferred to the liquidator.\n * @dev If the Comptroller address is not set, liquidation is a no-op and the function returns the success code.\n * @param liquidator The address repaying the VAI and seizing collateral\n * @param borrower The borrower of this VAI to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the VAI to repay\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function liquidateVAIFresh(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) internal returns (uint256, uint256) {\n if (address(comptroller) != address(0)) {\n accrueVAIInterest();\n\n /* Fail if liquidate not allowed */\n uint256 allowed = comptroller.liquidateBorrowAllowed(\n address(this),\n address(vTokenCollateral),\n liquidator,\n borrower,\n repayAmount\n );\n if (allowed != 0) {\n return (failOpaque(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\n }\n\n /* Verify vTokenCollateral market's block number equals current block number */\n //if (vTokenCollateral.accrualBlockNumber() != accrualBlockNumber) {\n if (vTokenCollateral.accrualBlockNumber() != getBlockNumber()) {\n return (fail(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n return (fail(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\n }\n\n /* Fail if repayAmount = 0 */\n if (repayAmount == 0) {\n return (fail(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\n }\n\n /* Fail if repayAmount = -1 */\n if (repayAmount == uint256(-1)) {\n return (fail(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\n }\n\n /* Fail if repayVAI fails */\n (uint256 repayBorrowError, uint256 actualRepayAmount) = repayVAIFresh(liquidator, borrower, repayAmount);\n if (repayBorrowError != uint256(Error.NO_ERROR)) {\n return (fail(Error(repayBorrowError), FailureInfo.VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We calculate the number of collateral tokens that will be seized */\n (uint256 amountSeizeError, uint256 seizeTokens) = comptroller.liquidateVAICalculateSeizeTokens(\n address(vTokenCollateral),\n actualRepayAmount\n );\n require(\n amountSeizeError == uint256(Error.NO_ERROR),\n \"VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\"\n );\n\n /* Revert if borrower collateral token balance < seizeTokens */\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \"VAI_LIQUIDATE_SEIZE_TOO_MUCH\");\n\n uint256 seizeError;\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\n\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\n require(seizeError == uint256(Error.NO_ERROR), \"token seizure failed\");\n\n /* We emit a LiquidateBorrow event */\n emit LiquidateVAI(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\n\n /* We call the defense hook */\n comptroller.liquidateBorrowVerify(\n address(this),\n address(vTokenCollateral),\n liquidator,\n borrower,\n actualRepayAmount,\n seizeTokens\n );\n\n return (uint256(Error.NO_ERROR), actualRepayAmount);\n }\n }\n\n /*** Admin Functions ***/\n\n /**\n * @notice Sets a new comptroller\n * @dev Admin function to set a new comptroller\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setComptroller(ComptrollerInterface comptroller_) external returns (uint256) {\n // Check caller is admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_COMPTROLLER_OWNER_CHECK);\n }\n\n ComptrollerInterface oldComptroller = comptroller;\n comptroller = comptroller_;\n emit NewComptroller(oldComptroller, comptroller_);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the prime token contract address\n * @param prime_ The new address of the prime token contract\n */\n function setPrimeToken(address prime_) external onlyAdmin {\n emit NewPrime(prime, prime_);\n prime = prime_;\n }\n\n /**\n * @notice Set the VAI token contract address\n * @param vai_ The new address of the VAI token contract\n */\n function setVAIToken(address vai_) external onlyAdmin {\n emit NewVaiToken(vai, vai_);\n vai = vai_;\n }\n\n /**\n * @notice Toggle mint only for prime holder\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function toggleOnlyPrimeHolderMint() external returns (uint256) {\n _ensureAllowed(\"toggleOnlyPrimeHolderMint()\");\n\n if (!mintEnabledOnlyForPrimeHolder && prime == address(0)) {\n return uint256(Error.REJECTION);\n }\n\n emit MintOnlyForPrimeHolder(mintEnabledOnlyForPrimeHolder, !mintEnabledOnlyForPrimeHolder);\n mintEnabledOnlyForPrimeHolder = !mintEnabledOnlyForPrimeHolder;\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @dev Local vars for avoiding stack-depth limits in calculating account total supply balance.\n * Note that `vTokenBalance` is the number of vTokens the account owns in the market,\n * whereas `borrowBalance` is the amount of underlying that the account has borrowed.\n */\n struct AccountAmountLocalVars {\n uint256 oErr;\n MathError mErr;\n uint256 sumSupply;\n uint256 marketSupply;\n uint256 sumBorrowPlusEffects;\n uint256 vTokenBalance;\n uint256 borrowBalance;\n uint256 exchangeRateMantissa;\n uint256 oraclePriceMantissa;\n Exp exchangeRate;\n Exp oraclePrice;\n Exp tokensToDenom;\n }\n\n /**\n * @notice Function that returns the amount of VAI a user can mint based on their account liquidy and the VAI mint rate\n * If mintEnabledOnlyForPrimeHolder is true, only Prime holders are able to mint VAI\n * @param minter The account to check mintable VAI\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol for details)\n * @return Mintable amount (with 18 decimals)\n */\n // solhint-disable-next-line code-complexity\n function getMintableVAI(address minter) public view returns (uint256, uint256) {\n if (mintEnabledOnlyForPrimeHolder && !IPrime(prime).isUserPrimeHolder(minter)) {\n return (uint256(Error.REJECTION), 0);\n }\n\n PriceOracle oracle = comptroller.oracle();\n VToken[] memory enteredMarkets = comptroller.getAssetsIn(minter);\n\n AccountAmountLocalVars memory vars; // Holds all our calculation results\n\n uint256 accountMintableVAI;\n uint256 i;\n\n /**\n * We use this formula to calculate mintable VAI amount.\n * totalSupplyAmount * VAIMintRate - (totalBorrowAmount + mintedVAIOf)\n */\n uint256 marketsCount = enteredMarkets.length;\n for (i = 0; i < marketsCount; i++) {\n (vars.oErr, vars.vTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = enteredMarkets[i]\n .getAccountSnapshot(minter);\n if (vars.oErr != 0) {\n // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades\n return (uint256(Error.SNAPSHOT_ERROR), 0);\n }\n vars.exchangeRate = Exp({ mantissa: vars.exchangeRateMantissa });\n\n // Get the normalized price of the asset\n vars.oraclePriceMantissa = oracle.getUnderlyingPrice(enteredMarkets[i]);\n if (vars.oraclePriceMantissa == 0) {\n return (uint256(Error.PRICE_ERROR), 0);\n }\n vars.oraclePrice = Exp({ mantissa: vars.oraclePriceMantissa });\n\n (vars.mErr, vars.tokensToDenom) = mulExp(vars.exchangeRate, vars.oraclePrice);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n // marketSupply = tokensToDenom * vTokenBalance\n (vars.mErr, vars.marketSupply) = mulScalarTruncate(vars.tokensToDenom, vars.vTokenBalance);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n (, uint256 collateralFactorMantissa) = comptroller.markets(address(enteredMarkets[i]));\n (vars.mErr, vars.marketSupply) = mulUInt(vars.marketSupply, collateralFactorMantissa);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n (vars.mErr, vars.marketSupply) = divUInt(vars.marketSupply, 1e18);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n (vars.mErr, vars.sumSupply) = addUInt(vars.sumSupply, vars.marketSupply);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n // sumBorrowPlusEffects += oraclePrice * borrowBalance\n (vars.mErr, vars.sumBorrowPlusEffects) = mulScalarTruncateAddUInt(\n vars.oraclePrice,\n vars.borrowBalance,\n vars.sumBorrowPlusEffects\n );\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n }\n\n uint256 totalMintedVAI = comptroller.mintedVAIs(minter);\n uint256 repayAmount = 0;\n\n if (totalMintedVAI > 0) {\n repayAmount = getVAIRepayAmount(minter);\n }\n\n (vars.mErr, vars.sumBorrowPlusEffects) = addUInt(vars.sumBorrowPlusEffects, repayAmount);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n (vars.mErr, accountMintableVAI) = mulUInt(vars.sumSupply, comptroller.vaiMintRate());\n require(vars.mErr == MathError.NO_ERROR, \"VAI_MINT_AMOUNT_CALCULATION_FAILED\");\n\n (vars.mErr, accountMintableVAI) = divUInt(accountMintableVAI, 10000);\n require(vars.mErr == MathError.NO_ERROR, \"VAI_MINT_AMOUNT_CALCULATION_FAILED\");\n\n (vars.mErr, accountMintableVAI) = subUInt(accountMintableVAI, vars.sumBorrowPlusEffects);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.REJECTION), 0);\n }\n\n return (uint256(Error.NO_ERROR), accountMintableVAI);\n }\n\n /**\n * @notice Update treasury data\n * @param newTreasuryGuardian New Treasury Guardian address\n * @param newTreasuryAddress New Treasury Address\n * @param newTreasuryPercent New fee percentage for minting VAI that is sent to the treasury\n */\n function _setTreasuryData(\n address newTreasuryGuardian,\n address newTreasuryAddress,\n uint256 newTreasuryPercent\n ) external returns (uint256) {\n // Check caller is admin\n if (!(msg.sender == admin || msg.sender == treasuryGuardian)) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_TREASURY_OWNER_CHECK);\n }\n\n require(newTreasuryPercent < 1e18, \"treasury percent cap overflow\");\n\n address oldTreasuryGuardian = treasuryGuardian;\n address oldTreasuryAddress = treasuryAddress;\n uint256 oldTreasuryPercent = treasuryPercent;\n\n treasuryGuardian = newTreasuryGuardian;\n treasuryAddress = newTreasuryAddress;\n treasuryPercent = newTreasuryPercent;\n\n emit NewTreasuryGuardian(oldTreasuryGuardian, newTreasuryGuardian);\n emit NewTreasuryAddress(oldTreasuryAddress, newTreasuryAddress);\n emit NewTreasuryPercent(oldTreasuryPercent, newTreasuryPercent);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Gets yearly VAI interest rate based on the VAI price\n * @return uint256 Yearly VAI interest rate\n */\n function getVAIRepayRate() public view returns (uint256) {\n PriceOracle oracle = comptroller.oracle();\n MathError mErr;\n\n if (baseRateMantissa > 0) {\n if (floatRateMantissa > 0) {\n uint256 oraclePrice = oracle.getUnderlyingPrice(VToken(getVAIAddress()));\n if (1e18 > oraclePrice) {\n uint256 delta;\n uint256 rate;\n\n (mErr, delta) = subUInt(1e18, oraclePrice);\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n (mErr, delta) = mulUInt(delta, floatRateMantissa);\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n (mErr, delta) = divUInt(delta, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n (mErr, rate) = addUInt(delta, baseRateMantissa);\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n return rate;\n } else {\n return baseRateMantissa;\n }\n } else {\n return baseRateMantissa;\n }\n } else {\n return 0;\n }\n }\n\n /**\n * @notice Get interest rate per block\n * @return uint256 Interest rate per bock\n */\n function getVAIRepayRatePerBlock() public view returns (uint256) {\n uint256 yearlyRate = getVAIRepayRate();\n\n MathError mErr;\n uint256 rate;\n\n (mErr, rate) = divUInt(yearlyRate, getBlocksPerYear());\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n return rate;\n }\n\n /**\n * @notice Get the last updated interest index for a VAI Minter\n * @param minter Address of VAI minter\n * @return uint256 Returns the interest rate index for a minter\n */\n function getVAIMinterInterestIndex(address minter) public view returns (uint256) {\n uint256 storedIndex = vaiMinterInterestIndex[minter];\n // If the user minted VAI before the stability fee was introduced, accrue\n // starting from stability fee launch\n if (storedIndex == 0) {\n return INITIAL_VAI_MINT_INDEX;\n }\n return storedIndex;\n }\n\n /**\n * @notice Get the current total VAI a user needs to repay\n * @param account The address of the VAI borrower\n * @return (uint256) The total amount of VAI the user needs to repay\n */\n function getVAIRepayAmount(address account) public view returns (uint256) {\n MathError mErr;\n uint256 delta;\n\n uint256 amount = comptroller.mintedVAIs(account);\n uint256 interest = pastVAIInterest[account];\n uint256 totalMintedVAI;\n uint256 newInterest;\n\n (mErr, totalMintedVAI) = subUInt(amount, interest);\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, delta) = subUInt(vaiMintIndex, getVAIMinterInterestIndex(account));\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, newInterest) = mulUInt(delta, totalMintedVAI);\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, newInterest) = divUInt(newInterest, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, amount) = addUInt(amount, newInterest);\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n return amount;\n }\n\n /**\n * @notice Calculate how much VAI the user needs to repay\n * @param borrower The address of the VAI borrower\n * @param repayAmount The amount of VAI being returned\n * @return Amount of VAI to be burned\n * @return Amount of VAI the user needs to pay in current interest\n * @return Amount of VAI the user needs to pay in past interest\n */\n function getVAICalculateRepayAmount(\n address borrower,\n uint256 repayAmount\n ) public view returns (uint256, uint256, uint256) {\n MathError mErr;\n uint256 totalRepayAmount = getVAIRepayAmount(borrower);\n uint256 currentInterest;\n\n (mErr, currentInterest) = subUInt(totalRepayAmount, comptroller.mintedVAIs(borrower));\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, currentInterest) = addUInt(pastVAIInterest[borrower], currentInterest);\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n\n uint256 burn;\n uint256 partOfCurrentInterest = currentInterest;\n uint256 partOfPastInterest = pastVAIInterest[borrower];\n\n if (repayAmount >= totalRepayAmount) {\n (mErr, burn) = subUInt(totalRepayAmount, currentInterest);\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n } else {\n uint256 delta;\n\n (mErr, delta) = mulUInt(repayAmount, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_PART_CALCULATION_FAILED\");\n\n (mErr, delta) = divUInt(delta, totalRepayAmount);\n require(mErr == MathError.NO_ERROR, \"VAI_PART_CALCULATION_FAILED\");\n\n uint256 totalMintedAmount;\n (mErr, totalMintedAmount) = subUInt(totalRepayAmount, currentInterest);\n require(mErr == MathError.NO_ERROR, \"VAI_MINTED_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, burn) = mulUInt(totalMintedAmount, delta);\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, burn) = divUInt(burn, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, partOfCurrentInterest) = mulUInt(currentInterest, delta);\n require(mErr == MathError.NO_ERROR, \"VAI_CURRENT_INTEREST_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, partOfCurrentInterest) = divUInt(partOfCurrentInterest, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_CURRENT_INTEREST_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, partOfPastInterest) = mulUInt(pastVAIInterest[borrower], delta);\n require(mErr == MathError.NO_ERROR, \"VAI_PAST_INTEREST_CALCULATION_FAILED\");\n\n (mErr, partOfPastInterest) = divUInt(partOfPastInterest, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_PAST_INTEREST_CALCULATION_FAILED\");\n }\n\n return (burn, partOfCurrentInterest, partOfPastInterest);\n }\n\n /**\n * @notice Accrue interest on outstanding minted VAI\n */\n function accrueVAIInterest() public {\n MathError mErr;\n uint256 delta;\n\n (mErr, delta) = mulUInt(getVAIRepayRatePerBlock(), getBlockNumber() - accrualBlockNumber);\n require(mErr == MathError.NO_ERROR, \"VAI_INTEREST_ACCRUE_FAILED\");\n\n (mErr, delta) = addUInt(delta, vaiMintIndex);\n require(mErr == MathError.NO_ERROR, \"VAI_INTEREST_ACCRUE_FAILED\");\n\n vaiMintIndex = delta;\n accrualBlockNumber = getBlockNumber();\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlAddress New address for the access control\n */\n function setAccessControl(address newAccessControlAddress) external onlyAdmin {\n _ensureNonzeroAddress(newAccessControlAddress);\n\n address oldAccessControlAddress = accessControl;\n accessControl = newAccessControlAddress;\n emit NewAccessControl(oldAccessControlAddress, accessControl);\n }\n\n /**\n * @notice Set VAI borrow base rate\n * @param newBaseRateMantissa the base rate multiplied by 10**18\n */\n function setBaseRate(uint256 newBaseRateMantissa) external {\n _ensureAllowed(\"setBaseRate(uint256)\");\n\n uint256 old = baseRateMantissa;\n baseRateMantissa = newBaseRateMantissa;\n emit NewVAIBaseRate(old, baseRateMantissa);\n }\n\n /**\n * @notice Set VAI borrow float rate\n * @param newFloatRateMantissa the VAI float rate multiplied by 10**18\n */\n function setFloatRate(uint256 newFloatRateMantissa) external {\n _ensureAllowed(\"setFloatRate(uint256)\");\n\n uint256 old = floatRateMantissa;\n floatRateMantissa = newFloatRateMantissa;\n emit NewVAIFloatRate(old, floatRateMantissa);\n }\n\n /**\n * @notice Set VAI stability fee receiver address\n * @param newReceiver the address of the VAI fee receiver\n */\n function setReceiver(address newReceiver) external onlyAdmin {\n _ensureNonzeroAddress(newReceiver);\n\n address old = receiver;\n receiver = newReceiver;\n emit NewVAIReceiver(old, newReceiver);\n }\n\n /**\n * @notice Set VAI mint cap\n * @param _mintCap the amount of VAI that can be minted\n */\n function setMintCap(uint256 _mintCap) external {\n _ensureAllowed(\"setMintCap(uint256)\");\n\n uint256 old = mintCap;\n mintCap = _mintCap;\n emit NewVAIMintCap(old, _mintCap);\n }\n\n function getBlockNumber() internal view returns (uint256) {\n return block.number;\n }\n\n function getBlocksPerYear() public view returns (uint256) {\n return 10512000; //(24 * 60 * 60 * 365) / 3;\n }\n\n /**\n * @notice Return the address of the VAI token\n * @return The address of VAI\n */\n function getVAIAddress() public view returns (address) {\n return vai;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n /*** Reentrancy Guard ***/\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n function _ensureAllowed(string memory functionSig) private view {\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \"access denied\");\n }\n\n /// @dev Reverts if the protocol is paused\n function _ensureNotPaused() private view {\n require(!comptroller.protocolPaused(), \"protocol is paused\");\n }\n\n /// @dev Reverts if the passed address is zero\n function _ensureNonzeroAddress(address someone) private pure {\n require(someone != address(0), \"can't be zero address\");\n }\n\n /// @dev Reverts if the passed amount is zero\n function _ensureNonzeroAmount(uint256 amount) private pure {\n require(amount > 0, \"amount can't be zero\");\n }\n}\n" + }, + "contracts/Tokens/VAI/VAIControllerInterface.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport { VTokenInterface } from \"../VTokens/VTokenInterfaces.sol\";\n\ncontract VAIControllerInterface {\n function mintVAI(uint256 mintVAIAmount) external returns (uint256);\n\n function repayVAI(uint256 amount) external returns (uint256, uint256);\n\n function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256);\n\n function liquidateVAI(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint256, uint256);\n\n function getMintableVAI(address minter) external view returns (uint256, uint256);\n\n function getVAIAddress() external view returns (address);\n\n function getVAIRepayAmount(address account) external view returns (uint256);\n}\n" + }, + "contracts/Tokens/VAI/VAIControllerStorage.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport { ComptrollerInterface } from \"../../Comptroller/ComptrollerInterface.sol\";\n\ncontract VAIUnitrollerAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of Unitroller\n */\n address public vaiControllerImplementation;\n\n /**\n * @notice Pending brains of Unitroller\n */\n address public pendingVAIControllerImplementation;\n}\n\ncontract VAIControllerStorageG1 is VAIUnitrollerAdminStorage {\n ComptrollerInterface public comptroller;\n\n struct VenusVAIState {\n /// @notice The last updated venusVAIMintIndex\n uint224 index;\n /// @notice The block number the index was last updated at\n uint32 block;\n }\n\n /// @notice The Venus VAI state\n VenusVAIState public venusVAIState;\n\n /// @notice The Venus VAI state initialized\n bool public isVenusVAIInitialized;\n\n /// @notice The Venus VAI minter index as of the last time they accrued XVS\n mapping(address => uint256) public venusVAIMinterIndex;\n}\n\ncontract VAIControllerStorageG2 is VAIControllerStorageG1 {\n /// @notice Treasury Guardian address\n address public treasuryGuardian;\n\n /// @notice Treasury address\n address public treasuryAddress;\n\n /// @notice Fee percent of accrued interest with decimal 18\n uint256 public treasuryPercent;\n\n /// @notice Guard variable for re-entrancy checks\n bool internal _notEntered;\n\n /// @notice The base rate for stability fee\n uint256 public baseRateMantissa;\n\n /// @notice The float rate for stability fee\n uint256 public floatRateMantissa;\n\n /// @notice The address for VAI interest receiver\n address public receiver;\n\n /// @notice Accumulator of the total earned interest rate since the opening of the market. For example: 0.6 (60%)\n uint256 public vaiMintIndex;\n\n /// @notice Block number that interest was last accrued at\n uint256 internal accrualBlockNumber;\n\n /// @notice Global vaiMintIndex as of the most recent balance-changing action for user\n mapping(address => uint256) internal vaiMinterInterestIndex;\n\n /// @notice Tracks the amount of mintedVAI of a user that represents the accrued interest\n mapping(address => uint256) public pastVAIInterest;\n\n /// @notice VAI mint cap\n uint256 public mintCap;\n\n /// @notice Access control manager address\n address public accessControl;\n}\n\ncontract VAIControllerStorageG3 is VAIControllerStorageG2 {\n /// @notice The address of the prime contract. It can be a ZERO address\n address public prime;\n\n /// @notice Tracks if minting is enabled only for prime token holders. Only used if prime is set\n bool public mintEnabledOnlyForPrimeHolder;\n}\n\ncontract VAIControllerStorageG4 is VAIControllerStorageG3 {\n /// @notice The address of the VAI token\n address internal vai;\n}\n" + }, + "contracts/Tokens/VAI/VAIUnitroller.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/ErrorReporter.sol\";\nimport \"./VAIControllerStorage.sol\";\n\n/**\n * @title VAI Unitroller\n * @author Venus\n * @notice This is the proxy contract for the VAIComptroller\n */\ncontract VAIUnitroller is VAIUnitrollerAdminStorage, VAIControllerErrorReporter {\n /**\n * @notice Emitted when pendingVAIControllerImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingVAIControllerImplementation is accepted, which means comptroller implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor() public {\n // Set admin to caller\n admin = msg.sender;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public returns (uint256) {\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK);\n }\n\n address oldPendingImplementation = pendingVAIControllerImplementation;\n\n pendingVAIControllerImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingVAIControllerImplementation);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts new implementation of comptroller. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public returns (uint256) {\n // Check caller is pendingImplementation\n if (msg.sender != pendingVAIControllerImplementation) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldImplementation = vaiControllerImplementation;\n address oldPendingImplementation = pendingVAIControllerImplementation;\n\n vaiControllerImplementation = pendingVAIControllerImplementation;\n\n pendingVAIControllerImplementation = address(0);\n\n emit NewImplementation(oldImplementation, vaiControllerImplementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingVAIControllerImplementation);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public returns (uint256) {\n // Check caller = admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK);\n }\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public returns (uint256) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = vaiControllerImplementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/Tokens/VRT/VRT.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/Tokenlock.sol\";\n\ncontract VRT is Tokenlock {\n /// @notice BEP-20 token name for this token\n string public constant name = \"Venus Reward Token\";\n\n /// @notice BEP-20 token symbol for this token\n string public constant symbol = \"VRT\";\n\n /// @notice BEP-20 token decimals for this token\n uint8 public constant decimals = 18;\n\n /// @notice Total number of tokens in circulation\n uint public constant totalSupply = 30000000000e18; // 30 billion VRT\n\n /// @notice Allowance amounts on behalf of others\n mapping(address => mapping(address => uint96)) internal allowances;\n\n /// @notice Official record of token balances for each account\n mapping(address => uint96) internal balances;\n\n /// @notice A record of each accounts delegate\n mapping(address => address) public delegates;\n\n /// @notice A checkpoint for marking number of votes from a given block\n struct Checkpoint {\n uint32 fromBlock;\n uint96 votes;\n }\n\n /// @notice A record of votes checkpoints for each account, by index\n mapping(address => mapping(uint32 => Checkpoint)) public checkpoints;\n\n /// @notice The number of checkpoints for each account\n mapping(address => uint32) public numCheckpoints;\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation struct used by the contract\n bytes32 public constant DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n /// @notice A record of states for signing / validating signatures\n mapping(address => uint) public nonces;\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /// @notice An event thats emitted when a delegate account's vote balance changes\n event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);\n\n /// @notice The standard BEP-20 transfer event\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /// @notice The standard BEP-20 approval event\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Construct a new VRT token\n * @param account The initial account to grant all the tokens\n */\n constructor(address account) public {\n balances[account] = uint96(totalSupply);\n emit Transfer(address(0), account, totalSupply);\n }\n\n /**\n * @notice Get the number of tokens `spender` is approved to spend on behalf of `account`\n * @param account The address of the account holding the funds\n * @param spender The address of the account spending the funds\n * @return The number of tokens approved\n */\n function allowance(address account, address spender) external view returns (uint) {\n return allowances[account][spender];\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint rawAmount) external validLock returns (bool) {\n uint96 amount;\n if (rawAmount == uint(-1)) {\n amount = uint96(-1);\n } else {\n amount = safe96(rawAmount, \"VRT::approve: amount exceeds 96 bits\");\n }\n\n allowances[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @notice Get the number of tokens held by the `account`\n * @param account The address of the account to get the balance of\n * @return The number of tokens held\n */\n function balanceOf(address account) external view returns (uint) {\n return balances[account];\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint rawAmount) external validLock returns (bool) {\n uint96 amount = safe96(rawAmount, \"VRT::transfer: amount exceeds 96 bits\");\n _transferTokens(msg.sender, dst, amount);\n return true;\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint rawAmount) external validLock returns (bool) {\n address spender = msg.sender;\n uint96 spenderAllowance = allowances[src][spender];\n uint96 amount = safe96(rawAmount, \"VRT::approve: amount exceeds 96 bits\");\n\n if (spender != src && spenderAllowance != uint96(-1)) {\n uint96 newAllowance = sub96(\n spenderAllowance,\n amount,\n \"VRT::transferFrom: transfer amount exceeds spender allowance\"\n );\n allowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n }\n\n _transferTokens(src, dst, amount);\n return true;\n }\n\n /**\n * @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The address to delegate votes to\n */\n function delegate(address delegatee) public validLock {\n return _delegate(msg.sender, delegatee);\n }\n\n /**\n * @notice Delegates votes from signatory to `delegatee`\n * @param delegatee The address to delegate votes to\n * @param nonce The contract state required to match the signature\n * @param expiry The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public validLock {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"VRT::delegateBySig: invalid signature\");\n require(nonce == nonces[signatory]++, \"VRT::delegateBySig: invalid nonce\");\n require(now <= expiry, \"VRT::delegateBySig: signature expired\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Gets the current votes balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for `account`\n */\n function getCurrentVotes(address account) external view returns (uint96) {\n uint32 nCheckpoints = numCheckpoints[account];\n return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n /**\n * @notice Determine the prior number of votes for an account as of a block number\n * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.\n * @param account The address of the account to check\n * @param blockNumber The block number to get the vote balance at\n * @return The number of votes the account had as of the given block\n */\n function getPriorVotes(address account, uint blockNumber) public view returns (uint96) {\n require(blockNumber < block.number, \"VRT::getPriorVotes: not yet determined\");\n\n uint32 nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n }\n\n // First check most recent balance\n if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {\n return checkpoints[account][nCheckpoints - 1].votes;\n }\n\n // Next check implicit zero balance\n if (checkpoints[account][0].fromBlock > blockNumber) {\n return 0;\n }\n\n uint32 lower = 0;\n uint32 upper = nCheckpoints - 1;\n while (upper > lower) {\n uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n Checkpoint memory cp = checkpoints[account][center];\n if (cp.fromBlock == blockNumber) {\n return cp.votes;\n } else if (cp.fromBlock < blockNumber) {\n lower = center;\n } else {\n upper = center - 1;\n }\n }\n return checkpoints[account][lower].votes;\n }\n\n function _delegate(address delegator, address delegatee) internal {\n address currentDelegate = delegates[delegator];\n uint96 delegatorBalance = balances[delegator];\n delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _transferTokens(address src, address dst, uint96 amount) internal {\n require(src != address(0), \"VRT::_transferTokens: cannot transfer from the zero address\");\n require(dst != address(0), \"VRT::_transferTokens: cannot transfer to the zero address\");\n\n balances[src] = sub96(balances[src], amount, \"VRT::_transferTokens: transfer amount exceeds balance\");\n balances[dst] = add96(balances[dst], amount, \"VRT::_transferTokens: transfer amount overflows\");\n emit Transfer(src, dst, amount);\n\n _moveDelegates(delegates[src], delegates[dst], amount);\n }\n\n function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {\n if (srcRep != dstRep && amount > 0) {\n if (srcRep != address(0)) {\n uint32 srcRepNum = numCheckpoints[srcRep];\n uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n uint96 srcRepNew = sub96(srcRepOld, amount, \"VRT::_moveVotes: vote amount underflows\");\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint96 dstRepNew = add96(dstRepOld, amount, \"VRT::_moveVotes: vote amount overflows\");\n _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {\n uint32 blockNumber = safe32(block.number, \"VRT::_writeCheckpoint: block number exceeds 32 bits\");\n\n if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {\n checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n } else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);\n numCheckpoints[delegatee] = nCheckpoints + 1;\n }\n\n emit DelegateVotesChanged(delegatee, oldVotes, newVotes);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n < 2 ** 32, errorMessage);\n return uint32(n);\n }\n\n function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {\n require(n < 2 ** 96, errorMessage);\n return uint96(n);\n }\n\n function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n uint96 c = a + b;\n require(c >= a, errorMessage);\n return c;\n }\n\n function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n function getChainId() internal pure returns (uint) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n return chainId;\n }\n}\n" + }, + "contracts/Tokens/VRT/VRTConverter.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/IBEP20.sol\";\nimport \"../../Utils/SafeBEP20.sol\";\nimport \"../XVS/IXVSVesting.sol\";\nimport \"./VRTConverterStorage.sol\";\nimport \"./VRTConverterProxy.sol\";\n\n/**\n * @title Venus's VRTConversion Contract\n * @author Venus\n */\ncontract VRTConverter is VRTConverterStorage {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n address public constant DEAD_ADDRESS = 0x000000000000000000000000000000000000dEaD;\n\n /// @notice decimal precision for VRT\n uint256 public constant vrtDecimalsMultiplier = 1e18;\n\n /// @notice decimal precision for XVS\n uint256 public constant xvsDecimalsMultiplier = 1e18;\n\n /// @notice Emitted when an admin set conversion info\n event ConversionInfoSet(\n uint256 conversionRatio,\n uint256 conversionStartTime,\n uint256 conversionPeriod,\n uint256 conversionEndTime\n );\n\n /// @notice Emitted when token conversion is done\n event TokenConverted(\n address reedeemer,\n address vrtAddress,\n uint256 vrtAmount,\n address xvsAddress,\n uint256 xvsAmount\n );\n\n /// @notice Emitted when an admin withdraw converted token\n event TokenWithdraw(address token, address to, uint256 amount);\n\n /// @notice Emitted when XVSVestingAddress is set\n event XVSVestingSet(address xvsVestingAddress);\n\n constructor() public {}\n\n function initialize(\n address _vrtAddress,\n address _xvsAddress,\n uint256 _conversionRatio,\n uint256 _conversionStartTime,\n uint256 _conversionPeriod\n ) public {\n require(msg.sender == admin, \"only admin may initialize the VRTConverter\");\n require(initialized == false, \"VRTConverter is already initialized\");\n\n require(_vrtAddress != address(0), \"vrtAddress cannot be Zero\");\n vrt = IBEP20(_vrtAddress);\n\n require(_xvsAddress != address(0), \"xvsAddress cannot be Zero\");\n xvs = IBEP20(_xvsAddress);\n\n require(_conversionRatio > 0, \"conversionRatio cannot be Zero\");\n conversionRatio = _conversionRatio;\n\n require(_conversionStartTime >= block.timestamp, \"conversionStartTime must be time in the future\");\n require(_conversionPeriod > 0, \"_conversionPeriod is invalid\");\n\n conversionStartTime = _conversionStartTime;\n conversionPeriod = _conversionPeriod;\n conversionEndTime = conversionStartTime.add(conversionPeriod);\n emit ConversionInfoSet(conversionRatio, conversionStartTime, conversionPeriod, conversionEndTime);\n\n totalVrtConverted = 0;\n _notEntered = true;\n initialized = true;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n /**\n * @notice sets XVSVestingProxy Address\n * @dev Note: If XVSVestingProxy is not set, then Conversion is not allowed\n * @param _xvsVestingAddress The XVSVestingProxy Address\n */\n function setXVSVesting(address _xvsVestingAddress) public {\n require(msg.sender == admin, \"only admin may initialize the Vault\");\n require(_xvsVestingAddress != address(0), \"xvsVestingAddress cannot be Zero\");\n xvsVesting = IXVSVesting(_xvsVestingAddress);\n emit XVSVestingSet(_xvsVestingAddress);\n }\n\n modifier isInitialized() {\n require(initialized == true, \"VRTConverter is not initialized\");\n _;\n }\n\n function isConversionActive() public view returns (bool) {\n uint256 currentTime = block.timestamp;\n if (currentTime >= conversionStartTime && currentTime <= conversionEndTime) {\n return true;\n }\n return false;\n }\n\n modifier checkForActiveConversionPeriod() {\n uint256 currentTime = block.timestamp;\n require(currentTime >= conversionStartTime, \"Conversion did not start yet\");\n require(currentTime <= conversionEndTime, \"Conversion Period Ended\");\n _;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n /**\n * @notice Transfer VRT and redeem XVS\n * @dev Note: If there is not enough XVS, we do not perform the conversion.\n * @param vrtAmount The amount of VRT\n */\n function convert(uint256 vrtAmount) external isInitialized checkForActiveConversionPeriod nonReentrant {\n require(\n address(xvsVesting) != address(0) && address(xvsVesting) != DEAD_ADDRESS,\n \"XVS-Vesting Address is not set\"\n );\n require(vrtAmount > 0, \"VRT amount must be non-zero\");\n totalVrtConverted = totalVrtConverted.add(vrtAmount);\n\n uint256 redeemAmount = vrtAmount.mul(conversionRatio).mul(xvsDecimalsMultiplier).div(1e18).div(\n vrtDecimalsMultiplier\n );\n\n emit TokenConverted(msg.sender, address(vrt), vrtAmount, address(xvs), redeemAmount);\n vrt.safeTransferFrom(msg.sender, DEAD_ADDRESS, vrtAmount);\n xvsVesting.deposit(msg.sender, redeemAmount);\n }\n\n /*** Admin Functions ***/\n function _become(VRTConverterProxy vrtConverterProxy) public {\n require(msg.sender == vrtConverterProxy.admin(), \"only proxy admin can change brains\");\n vrtConverterProxy._acceptImplementation();\n }\n}\n" + }, + "contracts/Tokens/VRT/VRTConverterProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VRTConverterStorage.sol\";\n\ncontract VRTConverterProxy is VRTConverterAdminStorage {\n /**\n * @notice Emitted when pendingImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingImplementation is accepted, which means VRTConverter implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor(\n address implementation_,\n address _vrtAddress,\n address _xvsAddress,\n uint256 _conversionRatio,\n uint256 _conversionStartTime,\n uint256 _conversionPeriod\n ) public nonZeroAddress(implementation_) nonZeroAddress(_vrtAddress) nonZeroAddress(_xvsAddress) {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_);\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(\n implementation_,\n abi.encodeWithSignature(\n \"initialize(address,address,uint256,uint256,uint256)\",\n _vrtAddress,\n _xvsAddress,\n _conversionRatio,\n _conversionStartTime,\n _conversionPeriod\n )\n );\n }\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n */\n function _setImplementation(address implementation_) public {\n require(msg.sender == admin, \"VRTConverterProxy::_setImplementation: admin only\");\n require(implementation_ != address(0), \"VRTConverterProxy::_setImplementation: invalid implementation address\");\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal nonZeroAddress(callee) returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(\n address newPendingImplementation\n ) public nonZeroAddress(newPendingImplementation) {\n require(msg.sender == admin, \"Only admin can set Pending Implementation\");\n\n address oldPendingImplementation = pendingImplementation;\n\n pendingImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Accepts new implementation of VRTConverter. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @dev return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public {\n // Check caller is pendingImplementation\n require(\n msg.sender == pendingImplementation,\n \"only address marked as pendingImplementation can accept Implementation\"\n );\n\n // Save current values for inclusion in log\n address oldImplementation = implementation;\n address oldPendingImplementation = pendingImplementation;\n\n implementation = pendingImplementation;\n\n pendingImplementation = address(0);\n\n emit NewImplementation(oldImplementation, implementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @dev return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public nonZeroAddress(newPendingAdmin) {\n // Check caller = admin\n require(msg.sender == admin, \"only admin can set pending admin\");\n require(newPendingAdmin != pendingAdmin, \"New pendingAdmin can not be same as the previous one\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @dev return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public {\n // Check caller is pendingAdmin\n require(msg.sender == pendingAdmin, \"only address marked as pendingAdmin can accept as Admin\");\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/Tokens/VRT/VRTConverterStorage.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/SafeMath.sol\";\nimport \"../../Utils/IBEP20.sol\";\nimport \"../XVS/IXVSVesting.sol\";\n\ncontract VRTConverterAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of VRTConverter\n */\n address public implementation;\n\n /**\n * @notice Pending brains of VRTConverter\n */\n address public pendingImplementation;\n}\n\ncontract VRTConverterStorage is VRTConverterAdminStorage {\n /// @notice Guard variable for re-entrancy checks\n bool public _notEntered;\n\n /// @notice indicator to check if the contract is initialized\n bool public initialized;\n\n /// @notice The VRT TOKEN!\n IBEP20 public vrt;\n\n /// @notice The XVS TOKEN!\n IBEP20 public xvs;\n\n /// @notice XVSVesting Contract reference\n IXVSVesting public xvsVesting;\n\n /// @notice Conversion ratio from VRT to XVS with decimal 18\n uint256 public conversionRatio;\n\n /// @notice total VRT converted to XVS\n uint256 public totalVrtConverted;\n\n /// @notice Conversion Start time in EpochSeconds\n uint256 public conversionStartTime;\n\n /// @notice ConversionPeriod in Seconds\n uint256 public conversionPeriod;\n\n /// @notice Conversion End time in EpochSeconds\n uint256 public conversionEndTime;\n}\n" + }, + "contracts/Tokens/VTokens/VBep20.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport { VToken, VBep20Interface, ComptrollerInterface, InterestRateModel, VTokenInterface } from \"./VToken.sol\";\nimport { EIP20Interface } from \"../EIP20Interface.sol\";\nimport { EIP20NonStandardInterface } from \"../EIP20NonStandardInterface.sol\";\n\n/**\n * @title Venus's VBep20 Contract\n * @notice vTokens which wrap an EIP-20 underlying\n * @author Venus\n */\ncontract VBep20 is VToken, VBep20Interface {\n /*** User Interface ***/\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Transfer event\n // @custom:event Emits Mint event\n function mint(uint mintAmount) external returns (uint) {\n (uint err, ) = mintInternal(mintAmount);\n return err;\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param receiver The account which is receiving the vTokens\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Transfer event\n // @custom:event Emits MintBehalf event\n function mintBehalf(address receiver, uint mintAmount) external returns (uint) {\n (uint err, ) = mintBehalfInternal(receiver, mintAmount);\n return err;\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeem(uint redeemTokens) external returns (uint) {\n return redeemInternal(msg.sender, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems assets on behalf of some other address. This function is only available\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemer The user on behalf of whom to redeem\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemBehalf(address redeemer, uint redeemTokens) external returns (uint) {\n require(comptroller.approvedDelegates(redeemer, msg.sender), \"not an approved delegate\");\n\n return redeemInternal(redeemer, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n return redeemUnderlyingInternal(msg.sender, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemer, on behalf of whom to redeem\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemUnderlyingBehalf(address redeemer, uint redeemAmount) external returns (uint) {\n require(comptroller.approvedDelegates(redeemer, msg.sender), \"not an approved delegate\");\n\n return redeemUnderlyingInternal(redeemer, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Borrow event on success\n function borrow(uint borrowAmount) external returns (uint) {\n return borrowInternal(msg.sender, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender borrows assets on behalf of some other address. This function is only available\n * for senders, explicitly marked as delegates of the borrower using `comptroller.updateDelegate`\n * @param borrower The borrower, on behalf of whom to borrow.\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Borrow event on success\n function borrowBehalf(address borrower, uint borrowAmount) external returns (uint) {\n require(comptroller.approvedDelegates(borrower, msg.sender), \"not an approved delegate\");\n return borrowInternal(borrower, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrow(uint repayAmount) external returns (uint) {\n (uint err, ) = repayBorrowInternal(repayAmount);\n return err;\n }\n\n /**\n * @notice Sender repays a borrow belonging to another borrowing account\n * @param borrower The account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) {\n (uint err, ) = repayBorrowBehalfInternal(borrower, repayAmount);\n return err;\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emit LiquidateBorrow event on success\n function liquidateBorrow(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint) {\n (uint err, ) = liquidateBorrowInternal(borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n /**\n * @notice The sender adds to reserves.\n * @param addAmount The amount of underlying tokens to add as reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits ReservesAdded event\n function _addReserves(uint addAmount) external returns (uint) {\n return _addReservesInternal(addAmount);\n }\n\n /**\n * @notice Initialize the new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n */\n function initialize(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) public {\n // VToken initialize does the bulk of the work\n super.initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_);\n\n // Set underlying and sanity check it\n underlying = underlying_;\n EIP20Interface(underlying).totalSupply();\n }\n\n /*** Safe Token ***/\n\n /**\n * @dev Similar to EIP20 transfer, except it handles a False result from `transferFrom` and reverts in that case.\n * This will revert due to insufficient balance or insufficient allowance.\n * This function returns the actual amount received,\n * which may be less than `amount` if there is a fee attached to the transfer.\n *\n * Note: This wrapper safely handles non-standard BEP-20 tokens that do not return a value.\n * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\n function doTransferIn(address from, uint amount) internal returns (uint) {\n uint balanceBefore = EIP20Interface(underlying).balanceOf(address(this));\n EIP20NonStandardInterface(underlying).transferFrom(from, address(this), amount);\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a compliant BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n require(success, \"TOKEN_TRANSFER_IN_FAILED\");\n\n // Calculate the amount that was *actually* transferred\n uint balanceAfter = EIP20Interface(underlying).balanceOf(address(this));\n require(balanceAfter >= balanceBefore, \"TOKEN_TRANSFER_IN_OVERFLOW\");\n return balanceAfter - balanceBefore; // underflow already checked above, just subtract\n }\n\n /**\n * @dev Similar to EIP20 transfer, except it handles a False success from `transfer` and returns an explanatory\n * error code rather than reverting. If caller has not called checked protocol's balance, this may revert due to\n * insufficient cash held in this contract. If caller has checked protocol's balance prior to this call, and verified\n * it is >= amount, this should not revert in normal conditions.\n *\n * Note: This wrapper safely handles non-standard BEP-20 tokens that do not return a value.\n * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\n function doTransferOut(address payable to, uint amount) internal {\n EIP20NonStandardInterface(underlying).transfer(to, amount);\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a compliant BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n require(success, \"TOKEN_TRANSFER_OUT_FAILED\");\n }\n\n /**\n * @notice Gets balance of this contract in terms of the underlying\n * @dev This excludes the value of the current message, if any\n * @return The quantity of underlying tokens owned by this contract\n */\n function getCashPrior() internal view returns (uint) {\n return EIP20Interface(underlying).balanceOf(address(this));\n }\n}\n" + }, + "contracts/Tokens/VTokens/VBep20Delegate.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport { VBep20 } from \"./VBep20.sol\";\nimport { VDelegateInterface } from \"./VTokenInterfaces.sol\";\n\n/**\n * @title Venus's VBep20Delegate Contract\n * @notice VTokens which wrap an EIP-20 underlying and are delegated to\n * @author Venus\n */\ncontract VBep20Delegate is VBep20, VDelegateInterface {\n /**\n * @notice Construct an empty delegate\n */\n constructor() public {}\n\n /**\n * @notice Called by the delegator on a delegate to initialize it for duty\n * @param data The encoded bytes data for any initialization\n */\n function _becomeImplementation(bytes memory data) public {\n // Shh -- currently unused\n data;\n\n // Shh -- we don't ever want this hook to be marked pure\n if (false) {\n implementation = address(0);\n }\n\n require(msg.sender == admin, \"only the admin may call _becomeImplementation\");\n }\n\n /**\n * @notice Called by the delegator on a delegate to forfeit its responsibility\n */\n function _resignImplementation() public {\n // Shh -- we don't ever want this hook to be marked pure\n if (false) {\n implementation = address(0);\n }\n\n require(msg.sender == admin, \"only the admin may call _resignImplementation\");\n }\n}\n" + }, + "contracts/Tokens/VTokens/VBep20Delegator.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VTokenInterfaces.sol\";\n\n/**\n * @title Venus's VBep20Delegator Contract\n * @notice vTokens which wrap an EIP-20 underlying and delegate to an implementation\n * @author Venus\n */\ncontract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterface {\n /**\n * @notice Construct a new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param implementation_ The address of the implementation the contract delegates to\n * @param becomeImplementationData The encoded args for becomeImplementation\n */\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_,\n address implementation_,\n bytes memory becomeImplementationData\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(\n implementation_,\n abi.encodeWithSignature(\n \"initialize(address,address,address,uint256,string,string,uint8)\",\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_\n )\n );\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_, false, becomeImplementationData);\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n\n /**\n * @notice Delegates execution to an implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n */\n function() external payable {\n require(msg.value == 0, \"VBep20Delegator:fallback: cannot send value to fallback\");\n\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function mint(uint mintAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"mint(uint256)\", mintAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function mintBehalf(address receiver, uint mintAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"mintBehalf(address,uint256)\", receiver, mintAmount)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying asset\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function redeem(uint redeemTokens) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"redeem(uint256)\", redeemTokens));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"redeemUnderlying(uint256)\", redeemAmount)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function borrow(uint borrowAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrow(uint256)\", borrowAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function repayBorrow(uint repayAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"repayBorrow(uint256)\", repayAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender repays a borrow belonging to another borrower\n * @param borrower The account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"repayBorrowBehalf(address,uint256)\", borrower, repayAmount)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function liquidateBorrow(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"liquidateBorrow(address,uint256,address)\", borrower, repayAmount, vTokenCollateral)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint amount) external returns (bool) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"transfer(address,uint256)\", dst, amount));\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"transferFrom(address,address,uint256)\", src, dst, amount)\n );\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved (-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"approve(address,uint256)\", spender, amount)\n );\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Get the underlying balance of the `owner`\n * @dev This also accrues interest in a transaction\n * @param owner The address of the account to query\n * @return The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"balanceOfUnderlying(address)\", owner));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return The total borrows with interest\n */\n function totalBorrowsCurrent() external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"totalBorrowsCurrent()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\n * @param account The address whose balance should be calculated after updating borrowIndex\n * @return The calculated balance\n */\n function borrowBalanceCurrent(address account) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrowBalanceCurrent(address)\", account));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Transfers collateral tokens (this market) to the liquidator.\n * @dev Will fail unless called by another vToken during the process of liquidation.\n * It's absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\n * @param liquidator The account receiving seized collateral\n * @param borrower The account having collateral seized\n * @param seizeTokens The number of vTokens to seize\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"seize(address,address,uint256)\", liquidator, borrower, seizeTokens)\n );\n return abi.decode(data, (uint));\n }\n\n /*** Admin Functions ***/\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setPendingAdmin(address)\", newPendingAdmin)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh\n * @dev Admin function to accrue interest and set a new reserve factor\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setReserveFactor(uint256)\", newReserveFactorMantissa)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accepts transfer of admin rights. `msg.sender` must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _acceptAdmin() external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_acceptAdmin()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrues interest and adds reserves by transferring from admin\n * @param addAmount Amount of reserves to add\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _addReserves(uint addAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_addReserves(uint256)\", addAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to admin\n * @param reduceAmount Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _reduceReserves(uint reduceAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_reduceReserves(uint256)\", reduceAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return The quantity of underlying asset owned by this contract\n */\n function getCash() external view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"getCash()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return The number of tokens allowed to be spent (-1 means infinite)\n */\n function allowance(address owner, address spender) external view returns (uint) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"allowance(address,address)\", owner, spender)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Get the token balance of the `owner`\n * @param owner The address of the account to query\n * @return The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"balanceOf(address)\", owner));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Get a snapshot of the account's balances and the cached exchange rate\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\n * @param account Address of the account to snapshot\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\n */\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"getAccountSnapshot(address)\", account)\n );\n return abi.decode(data, (uint, uint, uint, uint));\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"borrowRatePerBlock()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this vToken\n * @return The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"supplyRatePerBlock()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\n */\n // @custom:access Only callable by admin\n function _setImplementation(\n address implementation_,\n bool allowResign,\n bytes memory becomeImplementationData\n ) public {\n require(msg.sender == admin, \"VBep20Delegator::_setImplementation: Caller must be admin\");\n\n if (allowResign) {\n delegateToImplementation(abi.encodeWithSignature(\"_resignImplementation()\"));\n }\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n delegateToImplementation(abi.encodeWithSignature(\"_becomeImplementation(bytes)\", becomeImplementationData));\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"exchangeRateCurrent()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Applies accrued interest to total borrows and reserves.\n * @dev This calculates interest accrued from the last checkpointed block\n * up to the current block and writes new checkpoint to storage.\n */\n function accrueInterest() public returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"accrueInterest()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sets a new comptroller for the market\n * @dev Admin function to set a new comptroller\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setComptroller(address)\", newComptroller)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrues interest and updates the interest rate model using `_setInterestRateModelFresh`\n * @dev Admin function to accrue interest and update the interest rate model\n * @param newInterestRateModel The new interest rate model to use\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setInterestRateModel(address)\", newInterestRateModel)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Delegates execution to the implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateToImplementation(bytes memory data) public returns (bytes memory) {\n return delegateTo(implementation, data);\n }\n\n /**\n * @notice Delegates execution to an implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * There are an additional 2 prefix uints from the wrapper returndata, which we ignore since we make an extra hop.\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateToViewImplementation(bytes memory data) public view returns (bytes memory) {\n (bool success, bytes memory returnData) = address(this).staticcall(\n abi.encodeWithSignature(\"delegateToImplementation(bytes)\", data)\n );\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return abi.decode(returnData, (bytes));\n }\n\n /**\n * @notice Return the borrow balance of account based on stored data\n * @param account The address whose balance should be calculated\n * @return The calculated balance\n */\n function borrowBalanceStored(address account) public view returns (uint) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"borrowBalanceStored(address)\", account)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Calculates the exchange rate from the underlying to the VToken\n * @dev This function does not accrue interest before calculating the exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() public view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"exchangeRateStored()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n}\n" + }, + "contracts/Tokens/VTokens/VBep20Immutable.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VBep20.sol\";\n\n/**\n * @title Venus's VBep20Immutable Contract\n * @notice VTokens which wrap an EIP-20 underlying and are immutable\n * @author Venus\n */\ncontract VBep20Immutable is VBep20 {\n /**\n * @notice Construct a new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n */\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // Initialize the market\n initialize(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_\n );\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n}\n" + }, + "contracts/Tokens/VTokens/VBNB.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VToken.sol\";\n\n/**\n * @title Venus's vBNB Contract\n * @notice vToken which wraps BNB\n * @author Venus\n */\ncontract VBNB is VToken {\n /**\n * @notice Construct a new vBNB money market\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n */\n constructor(\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_);\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n\n /**\n * @notice Send BNB to VBNB to mint\n */\n function() external payable {\n (uint err, ) = mintInternal(msg.value);\n requireNoError(err, \"mint failed\");\n }\n\n /*** User Interface ***/\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Reverts upon any failure\n */\n // @custom:event Emits Transfer event\n // @custom:event Emits Mint event\n function mint() external payable {\n (uint err, ) = mintInternal(msg.value);\n requireNoError(err, \"mint failed\");\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeem(uint redeemTokens) external returns (uint) {\n return redeemInternal(msg.sender, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n return redeemUnderlyingInternal(msg.sender, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Borrow event on success\n function borrow(uint borrowAmount) external returns (uint) {\n return borrowInternal(msg.sender, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @dev Reverts upon any failure\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrow() external payable {\n (uint err, ) = repayBorrowInternal(msg.value);\n requireNoError(err, \"repayBorrow failed\");\n }\n\n /**\n * @notice Sender repays a borrow belonging to borrower\n * @dev Reverts upon any failure\n * @param borrower The account with the debt being payed off\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrowBehalf(address borrower) external payable {\n (uint err, ) = repayBorrowBehalfInternal(borrower, msg.value);\n requireNoError(err, \"repayBorrowBehalf failed\");\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @dev Reverts upon any failure\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n */\n // @custom:event Emit LiquidateBorrow event on success\n function liquidateBorrow(address borrower, VToken vTokenCollateral) external payable {\n (uint err, ) = liquidateBorrowInternal(borrower, msg.value, vTokenCollateral);\n requireNoError(err, \"liquidateBorrow failed\");\n }\n\n /*** Safe Token ***/\n\n /**\n * @notice Perform the actual transfer in, which is a no-op\n * @param from Address sending the BNB\n * @param amount Amount of BNB being sent\n * @return The actual amount of BNB transferred\n */\n function doTransferIn(address from, uint amount) internal returns (uint) {\n // Sanity checks\n require(msg.sender == from, \"sender mismatch\");\n require(msg.value == amount, \"value mismatch\");\n return amount;\n }\n\n function doTransferOut(address payable to, uint amount) internal {\n /* Send the BNB, with minimal gas and revert on failure */\n to.transfer(amount);\n }\n\n /**\n * @notice Gets balance of this contract in terms of BNB, before this message\n * @dev This excludes the value of the current message, if any\n * @return The quantity of BNB owned by this contract\n */\n function getCashPrior() internal view returns (uint) {\n (MathError err, uint startingBalance) = subUInt(address(this).balance, msg.value);\n require(err == MathError.NO_ERROR, \"cash prior math error\");\n return startingBalance;\n }\n\n function requireNoError(uint errCode, string memory message) internal pure {\n if (errCode == uint(Error.NO_ERROR)) {\n return;\n }\n\n bytes memory fullMessage = new bytes(bytes(message).length + 5);\n uint i;\n\n for (i = 0; i < bytes(message).length; i++) {\n fullMessage[i] = bytes(message)[i];\n }\n\n fullMessage[i + 0] = bytes1(uint8(32));\n fullMessage[i + 1] = bytes1(uint8(40));\n fullMessage[i + 2] = bytes1(uint8(48 + (errCode / 10)));\n fullMessage[i + 3] = bytes1(uint8(48 + (errCode % 10)));\n fullMessage[i + 4] = bytes1(uint8(41));\n\n require(errCode == uint(Error.NO_ERROR), string(fullMessage));\n }\n}\n" + }, + "contracts/Tokens/VTokens/VToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Comptroller/ComptrollerInterface.sol\";\nimport \"../../Utils/ErrorReporter.sol\";\nimport \"../../Utils/Exponential.sol\";\nimport \"../../Tokens/EIP20Interface.sol\";\nimport \"../../Tokens/EIP20NonStandardInterface.sol\";\nimport \"../../InterestRateModels/InterestRateModel.sol\";\nimport \"./VTokenInterfaces.sol\";\nimport { IAccessControlManagerV5 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\";\n\n/**\n * @title Venus's vToken Contract\n * @notice Abstract base for vTokens\n * @author Venus\n */\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\n struct MintLocalVars {\n MathError mathErr;\n uint exchangeRateMantissa;\n uint mintTokens;\n uint totalSupplyNew;\n uint accountTokensNew;\n uint actualMintAmount;\n }\n\n struct RedeemLocalVars {\n MathError mathErr;\n uint exchangeRateMantissa;\n uint redeemTokens;\n uint redeemAmount;\n uint totalSupplyNew;\n uint accountTokensNew;\n }\n\n struct BorrowLocalVars {\n MathError mathErr;\n uint accountBorrows;\n uint accountBorrowsNew;\n uint totalBorrowsNew;\n }\n\n struct RepayBorrowLocalVars {\n Error err;\n MathError mathErr;\n uint repayAmount;\n uint borrowerIndex;\n uint accountBorrows;\n uint accountBorrowsNew;\n uint totalBorrowsNew;\n uint actualRepayAmount;\n }\n\n /*** Reentrancy Guard ***/\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n // @custom:event Emits Transfer event\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n // @custom:event Emits Transfer event\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved (-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n // @custom:event Emits Approval event on successful approve\n function approve(address spender, uint256 amount) external returns (bool) {\n transferAllowances[msg.sender][spender] = amount;\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @notice Get the underlying balance of the `owner`\n * @dev This also accrues interest in a transaction\n * @param owner The address of the account to query\n * @return The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external returns (uint) {\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\n ensureNoMathError(mErr);\n return balance;\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return The total borrows with interest\n */\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\n require(accrueInterest() == uint(Error.NO_ERROR), \"accrue interest failed\");\n return totalBorrows;\n }\n\n /**\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\n * @param account The address whose balance should be calculated after updating borrowIndex\n * @return The calculated balance\n */\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\n require(accrueInterest() == uint(Error.NO_ERROR), \"accrue interest failed\");\n return borrowBalanceStored(account);\n }\n\n /**\n * @notice Transfers collateral tokens (this market) to the liquidator.\n * @dev Will fail unless called by another vToken during the process of liquidation.\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\n * @param liquidator The account receiving seized collateral\n * @param borrower The account having collateral seized\n * @param seizeTokens The number of vTokens to seize\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Transfer event\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\n // Check caller = admin\n ensureAdmin(msg.sender);\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits NewAdmin event on successful acceptance\n // @custom:event Emits NewPendingAdmin event with null new pending admin\n function _acceptAdmin() external returns (uint) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\n * @dev Governor function to accrue interest and set a new reserve factor\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits NewReserveFactor event\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\n ensureAllowed(\"_setReserveFactor(uint256)\");\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\n }\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\n return _setReserveFactorFresh(newReserveFactorMantissa_);\n }\n\n /**\n * @notice Sets the address of the access control manager of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlManagerAddress New address for the access control\n * @return uint 0=success, otherwise will revert\n */\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\n // Check caller is admin\n ensureAdmin(msg.sender);\n\n ensureNonZeroAddress(newAccessControlManagerAddress);\n\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\n accessControlManager = newAccessControlManagerAddress;\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\n * @param reduceAmount_ Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits ReservesReduced event\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\n ensureAllowed(\"_reduceReserves(uint256)\");\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\n }\n\n // If reserves were reduced in accrueInterest\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\n return _reduceReservesFresh(reduceAmount_);\n }\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return The number of tokens allowed to be spent (-1 means infinite)\n */\n function allowance(address owner, address spender) external view returns (uint256) {\n return transferAllowances[owner][spender];\n }\n\n /**\n * @notice Get the token balance of the `owner`\n * @param owner The address of the account to query\n * @return The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view returns (uint256) {\n return accountTokens[owner];\n }\n\n /**\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\n * @param account Address of the account to snapshot\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\n */\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\n uint vTokenBalance = accountTokens[account];\n uint borrowBalance;\n uint exchangeRateMantissa;\n\n MathError mErr;\n\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\n if (mErr != MathError.NO_ERROR) {\n return (uint(Error.MATH_ERROR), 0, 0, 0);\n }\n\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\n if (mErr != MathError.NO_ERROR) {\n return (uint(Error.MATH_ERROR), 0, 0, 0);\n }\n\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this vToken\n * @return The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view returns (uint) {\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view returns (uint) {\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return The quantity of underlying asset owned by this contract\n */\n function getCash() external view returns (uint) {\n return getCashPrior();\n }\n\n /**\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\n * @param newReduceReservesBlockDelta_ block difference value\n */\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\n require(newReduceReservesBlockDelta_ > 0, \"Invalid Input\");\n ensureAllowed(\"setReduceReservesBlockDelta(uint256)\");\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\n }\n\n /**\n * @notice Sets protocol share reserve contract address\n * @param protcolShareReserve_ The address of protocol share reserve contract\n */\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\n // Check caller is admin\n ensureAdmin(msg.sender);\n ensureNonZeroAddress(protcolShareReserve_);\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\n protocolShareReserve = protcolShareReserve_;\n }\n\n /**\n * @notice Initialize the money market\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ EIP-20 name of this token\n * @param symbol_ EIP-20 symbol of this token\n * @param decimals_ EIP-20 decimal precision of this token\n */\n function initialize(\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) public {\n ensureAdmin(msg.sender);\n require(accrualBlockNumber == 0 && borrowIndex == 0, \"market may only be initialized once\");\n\n // Set initial exchange rate\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\n require(initialExchangeRateMantissa > 0, \"initial exchange rate must be greater than zero.\");\n\n // Set the comptroller\n uint err = _setComptroller(comptroller_);\n require(err == uint(Error.NO_ERROR), \"setting comptroller failed\");\n\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\n accrualBlockNumber = block.number;\n borrowIndex = mantissaOne;\n\n // Set the interest rate model (depends on block number / borrow index)\n err = _setInterestRateModelFresh(interestRateModel_);\n require(err == uint(Error.NO_ERROR), \"setting interest rate model failed\");\n\n name = name_;\n symbol = symbol_;\n decimals = decimals_;\n\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\n _notEntered = true;\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public nonReentrant returns (uint) {\n require(accrueInterest() == uint(Error.NO_ERROR), \"accrue interest failed\");\n return exchangeRateStored();\n }\n\n /**\n * @notice Applies accrued interest to total borrows and reserves\n * @dev This calculates interest accrued from the last checkpointed block\n * up to the current block and writes new checkpoint to storage and\n * reduce spread reserves to protocol share reserve\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\n */\n // @custom:event Emits AccrueInterest event\n function accrueInterest() public returns (uint) {\n /* Remember the initial block number */\n uint currentBlockNumber = block.number;\n uint accrualBlockNumberPrior = accrualBlockNumber;\n\n /* Short-circuit accumulating 0 interest */\n if (accrualBlockNumberPrior == currentBlockNumber) {\n return uint(Error.NO_ERROR);\n }\n\n /* Read the previous values out of storage */\n uint cashPrior = getCashPrior();\n uint borrowsPrior = totalBorrows;\n uint reservesPrior = totalReserves;\n uint borrowIndexPrior = borrowIndex;\n\n /* Calculate the current borrow interest rate */\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\n require(borrowRateMantissa <= borrowRateMaxMantissa, \"borrow rate is absurdly high\");\n\n /* Calculate the number of blocks elapsed since the last accrual */\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\n ensureNoMathError(mathErr);\n\n /*\n * Calculate the interest accumulated into borrows and reserves and the new index:\n * simpleInterestFactor = borrowRate * blockDelta\n * interestAccumulated = simpleInterestFactor * totalBorrows\n * totalBorrowsNew = interestAccumulated + totalBorrows\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\n */\n\n Exp memory simpleInterestFactor;\n uint interestAccumulated;\n uint totalBorrowsNew;\n uint totalReservesNew;\n uint borrowIndexNew;\n\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\n Exp({ mantissa: reserveFactorMantissa }),\n interestAccumulated,\n reservesPrior\n );\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the previously calculated values into storage */\n accrualBlockNumber = currentBlockNumber;\n borrowIndex = borrowIndexNew;\n totalBorrows = totalBorrowsNew;\n totalReserves = totalReservesNew;\n\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\n ensureNoMathError(mathErr);\n if (blockDelta >= reduceReservesBlockDelta) {\n reduceReservesBlockNumber = currentBlockNumber;\n if (cashPrior < totalReservesNew) {\n _reduceReservesFresh(cashPrior);\n } else {\n _reduceReservesFresh(totalReservesNew);\n }\n }\n\n /* We emit an AccrueInterest event */\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets a new comptroller for the market\n * @dev Admin function to set a new comptroller\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits NewComptroller event\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\n // Check caller is admin\n ensureAdmin(msg.sender);\n\n ComptrollerInterface oldComptroller = comptroller;\n // Ensure invoke comptroller.isComptroller() returns true\n require(newComptroller.isComptroller(), \"marker method returned false\");\n\n // Set market's comptroller to newComptroller\n comptroller = newComptroller;\n\n // Emit NewComptroller(oldComptroller, newComptroller)\n emit NewComptroller(oldComptroller, newComptroller);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\n * @dev Governance function to accrue interest and update the interest rate model\n * @param newInterestRateModel_ The new interest rate model to use\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\n ensureAllowed(\"_setInterestRateModel(address)\");\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\n }\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\n return _setInterestRateModelFresh(newInterestRateModel_);\n }\n\n /**\n * @notice Calculates the exchange rate from the underlying to the VToken\n * @dev This function does not accrue interest before calculating the exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() public view returns (uint) {\n (MathError err, uint result) = exchangeRateStoredInternal();\n ensureNoMathError(err);\n return result;\n }\n\n /**\n * @notice Return the borrow balance of account based on stored data\n * @param account The address whose balance should be calculated\n * @return The calculated balance\n */\n function borrowBalanceStored(address account) public view returns (uint) {\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\n ensureNoMathError(err);\n return result;\n }\n\n /**\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\n * @dev Called by both `transfer` and `transferFrom` internally\n * @param spender The address of the account performing the transfer\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param tokens The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\n /* Fail if transfer not allowed */\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\n if (allowed != 0) {\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\n }\n\n /* Do not allow self-transfers */\n if (src == dst) {\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\n }\n\n /* Get the allowance, infinite for the account owner */\n uint startingAllowance = 0;\n if (spender == src) {\n startingAllowance = uint(-1);\n } else {\n startingAllowance = transferAllowances[src][spender];\n }\n\n /* Do the calculations, checking for {under,over}flow */\n MathError mathErr;\n uint allowanceNew;\n uint srvTokensNew;\n uint dstTokensNew;\n\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\n if (mathErr != MathError.NO_ERROR) {\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\n }\n\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\n if (mathErr != MathError.NO_ERROR) {\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\n }\n\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\n if (mathErr != MathError.NO_ERROR) {\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n accountTokens[src] = srvTokensNew;\n accountTokens[dst] = dstTokensNew;\n\n /* Eat some of the allowance (if necessary) */\n if (startingAllowance != uint(-1)) {\n transferAllowances[src][spender] = allowanceNew;\n }\n\n /* We emit a Transfer event */\n emit Transfer(src, dst, tokens);\n\n comptroller.transferVerify(address(this), src, dst, tokens);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\n */\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\n }\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n return mintFresh(msg.sender, mintAmount);\n }\n\n /**\n * @notice User supplies assets into the market and receives vTokens in exchange\n * @dev Assumes interest has already been accrued up to the current block\n * @param minter The address of the account which is supplying the assets\n * @param mintAmount The amount of the underlying asset to supply\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\n */\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\n /* Fail if mint not allowed */\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\n if (allowed != 0) {\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\n }\n\n MintLocalVars memory vars;\n\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\n if (vars.mathErr != MathError.NO_ERROR) {\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We call `doTransferIn` for the minter and the mintAmount.\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\n * side-effects occurred. The function returns the amount actually transferred,\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\n * of cash.\n */\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\n\n /*\n * We get the current exchange rate and calculate the number of vTokens to be minted:\n * mintTokens = actualMintAmount / exchangeRate\n */\n\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\n vars.actualMintAmount,\n Exp({ mantissa: vars.exchangeRateMantissa })\n );\n ensureNoMathError(vars.mathErr);\n\n /*\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\n * totalSupplyNew = totalSupply + mintTokens\n * accountTokensNew = accountTokens[minter] + mintTokens\n */\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\n ensureNoMathError(vars.mathErr);\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\n ensureNoMathError(vars.mathErr);\n\n /* We write previously calculated values into storage */\n totalSupply = vars.totalSupplyNew;\n accountTokens[minter] = vars.accountTokensNew;\n\n /* We emit a Mint event, and a Transfer event */\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\n emit Transfer(address(this), minter, vars.mintTokens);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\n\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param receiver The address of the account which is receiving the vTokens\n * @param mintAmount The amount of the underlying asset to supply\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\n */\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\n }\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\n }\n\n /**\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\n * @dev Assumes interest has already been accrued up to the current block\n * @param payer The address of the account which is paying the underlying token\n * @param receiver The address of the account which is receiving vToken\n * @param mintAmount The amount of the underlying asset to supply\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\n */\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\n ensureNonZeroAddress(receiver);\n /* Fail if mint not allowed */\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\n if (allowed != 0) {\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\n }\n\n MintLocalVars memory vars;\n\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\n if (vars.mathErr != MathError.NO_ERROR) {\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We call `doTransferIn` for the payer and the mintAmount.\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\n * side-effects occurred. The function returns the amount actually transferred,\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\n * of cash.\n */\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\n\n /*\n * We get the current exchange rate and calculate the number of vTokens to be minted:\n * mintTokens = actualMintAmount / exchangeRate\n */\n\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\n vars.actualMintAmount,\n Exp({ mantissa: vars.exchangeRateMantissa })\n );\n ensureNoMathError(vars.mathErr);\n\n /*\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\n * totalSupplyNew = totalSupply + mintTokens\n * accountTokensNew = accountTokens[receiver] + mintTokens\n */\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\n ensureNoMathError(vars.mathErr);\n\n /* We write previously calculated values into storage */\n totalSupply = vars.totalSupplyNew;\n accountTokens[receiver] = vars.accountTokensNew;\n\n /* We emit a MintBehalf event, and a Transfer event */\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\n emit Transfer(address(this), receiver, vars.mintTokens);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\n\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\n }\n\n /**\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemer The address of the account which is redeeming the tokens\n * @param receiver The receiver of the tokens\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function redeemInternal(\n address redeemer,\n address payable receiver,\n uint redeemTokens\n ) internal nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\n }\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\n }\n\n /**\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemer The address of the account which is redeeming the tokens\n * @param receiver The receiver of the tokens, if called by a delegate\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function redeemUnderlyingInternal(\n address redeemer,\n address payable receiver,\n uint redeemAmount\n ) internal nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\n }\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\n }\n\n /**\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\n * @dev Assumes interest has already been accrued up to the current block\n * @param redeemer The address of the account which is redeeming the tokens\n * @param receiver The receiver of the tokens\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // solhint-disable-next-line code-complexity\n function redeemFresh(\n address redeemer,\n address payable receiver,\n uint redeemTokensIn,\n uint redeemAmountIn\n ) internal returns (uint) {\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \"one of redeemTokensIn or redeemAmountIn must be zero\");\n\n RedeemLocalVars memory vars;\n\n /* exchangeRate = invoke Exchange Rate Stored() */\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\n ensureNoMathError(vars.mathErr);\n\n /* If redeemTokensIn > 0: */\n if (redeemTokensIn > 0) {\n /*\n * We calculate the exchange rate and the amount of underlying to be redeemed:\n * redeemTokens = redeemTokensIn\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\n */\n vars.redeemTokens = redeemTokensIn;\n\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\n Exp({ mantissa: vars.exchangeRateMantissa }),\n redeemTokensIn\n );\n ensureNoMathError(vars.mathErr);\n } else {\n /*\n * We get the current exchange rate and calculate the amount to be redeemed:\n * redeemTokens = redeemAmountIn / exchangeRate\n * redeemAmount = redeemAmountIn\n */\n\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\n redeemAmountIn,\n Exp({ mantissa: vars.exchangeRateMantissa })\n );\n ensureNoMathError(vars.mathErr);\n\n vars.redeemAmount = redeemAmountIn;\n }\n\n /* Fail if redeem not allowed */\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\n if (allowed != 0) {\n revert(\"math error\");\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n revert(\"math error\");\n }\n\n /*\n * We calculate the new total supply and redeemer balance, checking for underflow:\n * totalSupplyNew = totalSupply - redeemTokens\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\n */\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\n ensureNoMathError(vars.mathErr);\n\n /* Fail gracefully if protocol has insufficient cash */\n if (getCashPrior() < vars.redeemAmount) {\n revert(\"math error\");\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write previously calculated values into storage */\n totalSupply = vars.totalSupplyNew;\n accountTokens[redeemer] = vars.accountTokensNew;\n\n /*\n * We invoke doTransferOut for the receiver and the redeemAmount.\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * On success, the vToken has redeemAmount less of cash.\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\n */\n\n uint feeAmount;\n uint remainedAmount;\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\n (vars.mathErr, feeAmount) = mulUInt(\n vars.redeemAmount,\n IComptroller(address(comptroller)).treasuryPercent()\n );\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\n ensureNoMathError(vars.mathErr);\n\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\n\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\n } else {\n remainedAmount = vars.redeemAmount;\n }\n\n doTransferOut(receiver, remainedAmount);\n\n /* We emit a Transfer event, and a Redeem event */\n emit Transfer(redeemer, address(this), vars.redeemTokens);\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Receiver gets the borrow on behalf of the borrower address\n * @param borrower The borrower, on behalf of whom to borrow\n * @param receiver The account that would receive the funds (can be the same as the borrower)\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function borrowInternal(\n address borrower,\n address payable receiver,\n uint borrowAmount\n ) internal nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\n }\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\n return borrowFresh(borrower, receiver, borrowAmount);\n }\n\n /**\n * @notice Receiver gets the borrow on behalf of the borrower address\n * @dev Before calling this function, ensure that the interest has been accrued\n * @param borrower The borrower, on behalf of whom to borrow\n * @param receiver The account that would receive the funds (can be the same as the borrower)\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\n */\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\n /* Revert if borrow not allowed */\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\n if (allowed != 0) {\n revert(\"math error\");\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n revert(\"math error\");\n }\n\n /* Revert if protocol has insufficient underlying cash */\n if (getCashPrior() < borrowAmount) {\n revert(\"math error\");\n }\n\n BorrowLocalVars memory vars;\n\n /*\n * We calculate the new borrower and total borrow balances, failing on overflow:\n * accountBorrowsNew = accountBorrows + borrowAmount\n * totalBorrowsNew = totalBorrows + borrowAmount\n */\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\n ensureNoMathError(vars.mathErr);\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the previously calculated values into storage */\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = vars.totalBorrowsNew;\n\n /*\n * We invoke doTransferOut for the receiver and the borrowAmount.\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * On success, the vToken borrowAmount less of cash.\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\n */\n doTransferOut(receiver, borrowAmount);\n\n /* We emit a Borrow event */\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\n }\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\n }\n\n /**\n * @notice Sender repays a borrow belonging to another borrowing account\n * @param borrower The account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\n }\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\n }\n\n /**\n * @notice Borrows are repaid by another user (possibly the borrower).\n * @param payer The account paying off the borrow\n * @param borrower The account with the debt being payed off\n * @param repayAmount The amount of undelrying tokens being returned\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\n /* Fail if repayBorrow not allowed */\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\n if (allowed != 0) {\n return (\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\n 0\n );\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\n }\n\n RepayBorrowLocalVars memory vars;\n\n /* We remember the original borrowerIndex for verification purposes */\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\n\n /* We fetch the amount the borrower owes, with accumulated interest */\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\n if (vars.mathErr != MathError.NO_ERROR) {\n return (\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\n uint(vars.mathErr)\n ),\n 0\n );\n }\n\n /* If repayAmount == -1, repayAmount = accountBorrows */\n if (repayAmount == uint(-1)) {\n vars.repayAmount = vars.accountBorrows;\n } else {\n vars.repayAmount = repayAmount;\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We call doTransferIn for the payer and the repayAmount\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * On success, the vToken holds an additional repayAmount of cash.\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\n * it returns the amount actually transferred, in case of a fee.\n */\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\n\n /*\n * We calculate the new borrower and total borrow balances, failing on underflow:\n * accountBorrowsNew = accountBorrows - actualRepayAmount\n * totalBorrowsNew = totalBorrows - actualRepayAmount\n */\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\n ensureNoMathError(vars.mathErr);\n\n /* We write the previously calculated values into storage */\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = vars.totalBorrowsNew;\n\n /* We emit a RepayBorrow event */\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\n\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n function liquidateBorrowInternal(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\n }\n\n error = vTokenCollateral.accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\n }\n\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\n }\n\n /**\n * @notice The liquidator liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param liquidator The address repaying the borrow and seizing collateral\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n // solhint-disable-next-line code-complexity\n function liquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) internal returns (uint, uint) {\n /* Fail if liquidate not allowed */\n uint allowed = comptroller.liquidateBorrowAllowed(\n address(this),\n address(vTokenCollateral),\n liquidator,\n borrower,\n repayAmount\n );\n if (allowed != 0) {\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\n }\n\n /* Verify vTokenCollateral market's block number equals current block number */\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\n }\n\n /* Fail if repayAmount = 0 */\n if (repayAmount == 0) {\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\n }\n\n /* Fail if repayAmount = -1 */\n if (repayAmount == uint(-1)) {\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\n }\n\n /* Fail if repayBorrow fails */\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\n if (repayBorrowError != uint(Error.NO_ERROR)) {\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We calculate the number of collateral tokens that will be seized */\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\n address(this),\n address(vTokenCollateral),\n actualRepayAmount\n );\n require(amountSeizeError == uint(Error.NO_ERROR), \"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\");\n\n /* Revert if borrower collateral token balance < seizeTokens */\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \"LIQUIDATE_SEIZE_TOO_MUCH\");\n\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\n uint seizeError;\n if (address(vTokenCollateral) == address(this)) {\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\n } else {\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\n }\n\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\n require(seizeError == uint(Error.NO_ERROR), \"token seizure failed\");\n\n /* We emit a LiquidateBorrow event */\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.liquidateBorrowVerify(\n address(this),\n address(vTokenCollateral),\n liquidator,\n borrower,\n actualRepayAmount,\n seizeTokens\n );\n\n return (uint(Error.NO_ERROR), actualRepayAmount);\n }\n\n /**\n * @notice Transfers collateral tokens (this market) to the liquidator.\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\n * @param liquidator The account receiving seized collateral\n * @param borrower The account having collateral seized\n * @param seizeTokens The number of vTokens to seize\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function seizeInternal(\n address seizerToken,\n address liquidator,\n address borrower,\n uint seizeTokens\n ) internal returns (uint) {\n /* Fail if seize not allowed */\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\n if (allowed != 0) {\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\n }\n\n MathError mathErr;\n uint borrowerTokensNew;\n uint liquidatorTokensNew;\n\n /*\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\n */\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\n if (mathErr != MathError.NO_ERROR) {\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\n }\n\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\n if (mathErr != MathError.NO_ERROR) {\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the previously calculated values into storage */\n accountTokens[borrower] = borrowerTokensNew;\n accountTokens[liquidator] = liquidatorTokensNew;\n\n /* Emit a Transfer event */\n emit Transfer(borrower, liquidator, seizeTokens);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\n * @dev Governance function to set a new reserve factor\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\n // Verify market's block number equals current block number\n if (accrualBlockNumber != block.number) {\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\n }\n\n // Check newReserveFactor ≤ maxReserveFactor\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\n }\n\n uint oldReserveFactorMantissa = reserveFactorMantissa;\n reserveFactorMantissa = newReserveFactorMantissa;\n\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\n * @param addAmount Amount of addition to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\n }\n\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\n (error, ) = _addReservesFresh(addAmount);\n return error;\n }\n\n /**\n * @notice Add reserves by transferring from caller\n * @dev Requires fresh interest accrual\n * @param addAmount Amount of addition to reserves\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\n */\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\n // totalReserves + actualAddAmount\n uint totalReservesNew;\n uint actualAddAmount;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We call doTransferIn for the caller and the addAmount\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * On success, the vToken holds an additional addAmount of cash.\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\n * it returns the amount actually transferred, in case of a fee.\n */\n\n actualAddAmount = doTransferIn(msg.sender, addAmount);\n\n totalReservesNew = totalReserves + actualAddAmount;\n\n /* Revert on overflow */\n require(totalReservesNew >= totalReserves, \"add reserves unexpected overflow\");\n\n // Store reserves[n+1] = reserves[n] + actualAddAmount\n totalReserves = totalReservesNew;\n\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\n\n /* Return (NO_ERROR, actualAddAmount) */\n return (uint(Error.NO_ERROR), actualAddAmount);\n }\n\n /**\n * @notice Reduces reserves by transferring to protocol share reserve contract\n * @dev Requires fresh interest accrual\n * @param reduceAmount Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\n if (reduceAmount == 0) {\n return uint(Error.NO_ERROR);\n }\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != block.number) {\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\n }\n\n // Fail gracefully if protocol has insufficient underlying cash\n if (getCashPrior() < reduceAmount) {\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\n }\n\n // Check reduceAmount ≤ reserves[n] (totalReserves)\n if (reduceAmount > totalReserves) {\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n // totalReserves - reduceAmount\n uint totalReservesNew = totalReserves - reduceAmount;\n\n // Store reserves[n+1] = reserves[n] - reduceAmount\n totalReserves = totalReservesNew;\n\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\n doTransferOut(protocolShareReserve, reduceAmount);\n\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\n address(comptroller),\n underlying,\n IProtocolShareReserveV5.IncomeType.SPREAD\n );\n\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice updates the interest rate model (requires fresh interest accrual)\n * @dev Governance function to update the interest rate model\n * @param newInterestRateModel the new interest rate model to use\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\n // Used to store old model for use in the event that is emitted on success\n InterestRateModel oldInterestRateModel;\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != block.number) {\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\n }\n\n // Track the market's current interest rate model\n oldInterestRateModel = interestRateModel;\n\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\n require(newInterestRateModel.isInterestRateModel(), \"marker method returned false\");\n\n // Set the interest rate model to newInterestRateModel\n interestRateModel = newInterestRateModel;\n\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\n\n return uint(Error.NO_ERROR);\n }\n\n /*** Safe Token ***/\n\n /**\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\n * This may revert due to insufficient balance or insufficient allowance.\n */\n function doTransferIn(address from, uint amount) internal returns (uint);\n\n /**\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\n */\n function doTransferOut(address payable to, uint amount) internal;\n\n /**\n * @notice Return the borrow balance of account based on stored data\n * @param account The address whose balance should be calculated\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\n */\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\n /* Note: we do not assert that the market is up to date */\n MathError mathErr;\n uint principalTimesIndex;\n uint result;\n\n /* Get borrowBalance and borrowIndex */\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\n\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\n */\n if (borrowSnapshot.principal == 0) {\n return (MathError.NO_ERROR, 0);\n }\n\n /* Calculate new borrow balance using the interest index:\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\n */\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\n if (mathErr != MathError.NO_ERROR) {\n return (mathErr, 0);\n }\n\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\n if (mathErr != MathError.NO_ERROR) {\n return (mathErr, 0);\n }\n\n return (MathError.NO_ERROR, result);\n }\n\n /**\n * @notice Calculates the exchange rate from the underlying to the vToken\n * @dev This function does not accrue interest before calculating the exchange rate\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\n */\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\n uint _totalSupply = totalSupply;\n if (_totalSupply == 0) {\n /*\n * If there are no tokens minted:\n * exchangeRate = initialExchangeRate\n */\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\n } else {\n /*\n * Otherwise:\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\n */\n uint totalCash = getCashPrior();\n uint cashPlusBorrowsMinusReserves;\n Exp memory exchangeRate;\n MathError mathErr;\n\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\n if (mathErr != MathError.NO_ERROR) {\n return (mathErr, 0);\n }\n\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\n if (mathErr != MathError.NO_ERROR) {\n return (mathErr, 0);\n }\n\n return (MathError.NO_ERROR, exchangeRate.mantissa);\n }\n }\n\n function ensureAllowed(string memory functionSig) private view {\n require(\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\n \"access denied\"\n );\n }\n\n function ensureAdmin(address caller_) private view {\n require(caller_ == admin, \"Unauthorized\");\n }\n\n function ensureNoMathError(MathError mErr) private pure {\n require(mErr == MathError.NO_ERROR, \"math error\");\n }\n\n function ensureNonZeroAddress(address address_) private pure {\n require(address_ != address(0), \"zero address\");\n }\n\n /*** Safe Token ***/\n\n /**\n * @notice Gets balance of this contract in terms of the underlying\n * @dev This excludes the value of the current message, if any\n * @return The quantity of underlying owned by this contract\n */\n function getCashPrior() internal view returns (uint);\n}\n" + }, + "contracts/Tokens/VTokens/VTokenInterfaces.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Comptroller/ComptrollerInterface.sol\";\nimport \"../../InterestRateModels/InterestRateModel.sol\";\n\ninterface IProtocolShareReserveV5 {\n enum IncomeType {\n SPREAD,\n LIQUIDATION\n }\n\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\n}\n\ncontract VTokenStorageBase {\n /**\n * @notice Container for borrow balance information\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\n */\n struct BorrowSnapshot {\n uint principal;\n uint interestIndex;\n }\n\n /**\n * @dev Guard variable for re-entrancy checks\n */\n bool internal _notEntered;\n\n /**\n * @notice EIP-20 token name for this token\n */\n string public name;\n\n /**\n * @notice EIP-20 token symbol for this token\n */\n string public symbol;\n\n /**\n * @notice EIP-20 token decimals for this token\n */\n uint8 public decimals;\n\n /**\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\n */\n\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\n\n /**\n * @notice Maximum fraction of interest that can be set aside for reserves\n */\n uint internal constant reserveFactorMaxMantissa = 1e18;\n\n /**\n * @notice Administrator for this contract\n */\n address payable public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address payable public pendingAdmin;\n\n /**\n * @notice Contract which oversees inter-vToken operations\n */\n ComptrollerInterface public comptroller;\n\n /**\n * @notice Model which tells what the current interest rate should be\n */\n InterestRateModel public interestRateModel;\n\n /**\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\n */\n uint internal initialExchangeRateMantissa;\n\n /**\n * @notice Fraction of interest currently set aside for reserves\n */\n uint public reserveFactorMantissa;\n\n /**\n * @notice Block number that interest was last accrued at\n */\n uint public accrualBlockNumber;\n\n /**\n * @notice Accumulator of the total earned interest rate since the opening of the market\n */\n uint public borrowIndex;\n\n /**\n * @notice Total amount of outstanding borrows of the underlying in this market\n */\n uint public totalBorrows;\n\n /**\n * @notice Total amount of reserves of the underlying held in this market\n */\n uint public totalReserves;\n\n /**\n * @notice Total number of tokens in circulation\n */\n uint public totalSupply;\n\n /**\n * @notice Official record of token balances for each account\n */\n mapping(address => uint) internal accountTokens;\n\n /**\n * @notice Approved token transfer amounts on behalf of others\n */\n mapping(address => mapping(address => uint)) internal transferAllowances;\n\n /**\n * @notice Mapping of account addresses to outstanding borrow balances\n */\n mapping(address => BorrowSnapshot) internal accountBorrows;\n\n /**\n * @notice Underlying asset for this VToken\n */\n address public underlying;\n\n /**\n * @notice Implementation address for this contract\n */\n address public implementation;\n\n /**\n * @notice delta block after which reserves will be reduced\n */\n uint public reduceReservesBlockDelta;\n\n /**\n * @notice last block number at which reserves were reduced\n */\n uint public reduceReservesBlockNumber;\n\n /**\n * @notice address of protocol share reserve contract\n */\n address payable public protocolShareReserve;\n\n /**\n * @notice address of accessControlManager\n */\n\n address public accessControlManager;\n}\n\ncontract VTokenStorage is VTokenStorageBase {\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\ncontract VTokenInterface is VTokenStorage {\n /**\n * @notice Indicator that this is a vToken contract (for inspection)\n */\n bool public constant isVToken = true;\n\n /*** Market Events ***/\n\n /**\n * @notice Event emitted when interest is accrued\n */\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\n\n /**\n * @notice Event emitted when tokens are minted\n */\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\n\n /**\n * @notice Event emitted when tokens are minted behalf by payer to receiver\n */\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\n\n /**\n * @notice Event emitted when tokens are redeemed\n */\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\n\n /**\n * @notice Event emitted when tokens are redeemed and fee is transferred\n */\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\n\n /**\n * @notice Event emitted when underlying is borrowed\n */\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\n\n /**\n * @notice Event emitted when a borrow is repaid\n */\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\n\n /**\n * @notice Event emitted when a borrow is liquidated\n */\n event LiquidateBorrow(\n address liquidator,\n address borrower,\n uint repayAmount,\n address vTokenCollateral,\n uint seizeTokens\n );\n\n /*** Admin Events ***/\n\n /**\n * @notice Event emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n /**\n * @notice Event emitted when comptroller is changed\n */\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\n\n /**\n * @notice Event emitted when interestRateModel is changed\n */\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\n\n /**\n * @notice Event emitted when the reserve factor is changed\n */\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\n\n /**\n * @notice Event emitted when the reserves are added\n */\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\n\n /**\n * @notice Event emitted when the reserves are reduced\n */\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\n\n /**\n * @notice EIP20 Transfer event\n */\n event Transfer(address indexed from, address indexed to, uint amount);\n\n /**\n * @notice EIP20 Approval event\n */\n event Approval(address indexed owner, address indexed spender, uint amount);\n\n /**\n * @notice Event emitted when block delta for reduce reserves get updated\n */\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\n\n /**\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\n */\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\n\n /**\n * @notice Failure event\n */\n event Failure(uint error, uint info, uint detail);\n\n /// @notice Emitted when access control address is changed by admin\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\n\n /*** User Interface ***/\n\n function transfer(address dst, uint amount) external returns (bool);\n\n function transferFrom(address src, address dst, uint amount) external returns (bool);\n\n function approve(address spender, uint amount) external returns (bool);\n\n function balanceOfUnderlying(address owner) external returns (uint);\n\n function totalBorrowsCurrent() external returns (uint);\n\n function borrowBalanceCurrent(address account) external returns (uint);\n\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\n\n /*** Admin Function ***/\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\n\n /*** Admin Function ***/\n function _acceptAdmin() external returns (uint);\n\n /*** Admin Function ***/\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\n\n /*** Admin Function ***/\n function _reduceReserves(uint reduceAmount) external returns (uint);\n\n function balanceOf(address owner) external view returns (uint);\n\n function allowance(address owner, address spender) external view returns (uint);\n\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\n\n function borrowRatePerBlock() external view returns (uint);\n\n function supplyRatePerBlock() external view returns (uint);\n\n function getCash() external view returns (uint);\n\n function exchangeRateCurrent() public returns (uint);\n\n function accrueInterest() public returns (uint);\n\n /*** Admin Function ***/\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\n\n /*** Admin Function ***/\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\n\n function borrowBalanceStored(address account) public view returns (uint);\n\n function exchangeRateStored() public view returns (uint);\n}\n\ncontract VBep20Interface {\n /*** User Interface ***/\n\n function mint(uint mintAmount) external returns (uint);\n\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\n\n function redeem(uint redeemTokens) external returns (uint);\n\n function redeemUnderlying(uint redeemAmount) external returns (uint);\n\n function borrow(uint borrowAmount) external returns (uint);\n\n function repayBorrow(uint repayAmount) external returns (uint);\n\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\n\n function liquidateBorrow(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint);\n\n /*** Admin Functions ***/\n\n function _addReserves(uint addAmount) external returns (uint);\n}\n\ncontract VDelegatorInterface {\n /**\n * @notice Emitted when implementation is changed\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\n */\n function _setImplementation(\n address implementation_,\n bool allowResign,\n bytes memory becomeImplementationData\n ) public;\n}\n\ncontract VDelegateInterface {\n /**\n * @notice Called by the delegator on a delegate to initialize it for duty\n * @dev Should revert if any issues arise which make it unfit for delegation\n * @param data The encoded bytes data for any initialization\n */\n function _becomeImplementation(bytes memory data) public;\n\n /**\n * @notice Called by the delegator on a delegate to forfeit its responsibility\n */\n function _resignImplementation() public;\n}\n" + }, + "contracts/Tokens/XVS/IXVSVesting.sol": { + "content": "pragma solidity ^0.5.16;\n\ninterface IXVSVesting {\n /// @param _recipient Address of the Vesting. recipient entitled to claim the vested funds\n /// @param _amount Total number of tokens Vested\n function deposit(address _recipient, uint256 _amount) external;\n}\n" + }, + "contracts/Tokens/XVS/XVS.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/Tokenlock.sol\";\n\ncontract XVS is Tokenlock {\n /// @notice BEP-20 token name for this token\n string public constant name = \"Venus\";\n\n /// @notice BEP-20 token symbol for this token\n string public constant symbol = \"XVS\";\n\n /// @notice BEP-20 token decimals for this token\n uint8 public constant decimals = 18;\n\n /// @notice Total number of tokens in circulation\n uint public constant totalSupply = 30000000e18; // 30 million XVS\n\n /// @notice Allowance amounts on behalf of others\n mapping(address => mapping(address => uint96)) internal allowances;\n\n /// @notice Official record of token balances for each account\n mapping(address => uint96) internal balances;\n\n /// @notice A record of each accounts delegate\n mapping(address => address) public delegates;\n\n /// @notice A checkpoint for marking number of votes from a given block\n struct Checkpoint {\n uint32 fromBlock;\n uint96 votes;\n }\n\n /// @notice A record of votes checkpoints for each account, by index\n mapping(address => mapping(uint32 => Checkpoint)) public checkpoints;\n\n /// @notice The number of checkpoints for each account\n mapping(address => uint32) public numCheckpoints;\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation struct used by the contract\n bytes32 public constant DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n /// @notice A record of states for signing / validating signatures\n mapping(address => uint) public nonces;\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /// @notice An event thats emitted when a delegate account's vote balance changes\n event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);\n\n /// @notice The standard BEP-20 transfer event\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /// @notice The standard BEP-20 approval event\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Construct a new XVS token\n * @param account The initial account to grant all the tokens\n */\n constructor(address account) public {\n balances[account] = uint96(totalSupply);\n emit Transfer(address(0), account, totalSupply);\n }\n\n /**\n * @notice Get the number of tokens `spender` is approved to spend on behalf of `account`\n * @param account The address of the account holding the funds\n * @param spender The address of the account spending the funds\n * @return The number of tokens approved\n */\n function allowance(address account, address spender) external view returns (uint) {\n return allowances[account][spender];\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint rawAmount) external validLock returns (bool) {\n uint96 amount;\n if (rawAmount == uint(-1)) {\n amount = uint96(-1);\n } else {\n amount = safe96(rawAmount, \"XVS::approve: amount exceeds 96 bits\");\n }\n\n allowances[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @notice Get the number of tokens held by the `account`\n * @param account The address of the account to get the balance of\n * @return The number of tokens held\n */\n function balanceOf(address account) external view returns (uint) {\n return balances[account];\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint rawAmount) external validLock returns (bool) {\n uint96 amount = safe96(rawAmount, \"XVS::transfer: amount exceeds 96 bits\");\n _transferTokens(msg.sender, dst, amount);\n return true;\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint rawAmount) external validLock returns (bool) {\n address spender = msg.sender;\n uint96 spenderAllowance = allowances[src][spender];\n uint96 amount = safe96(rawAmount, \"XVS::approve: amount exceeds 96 bits\");\n\n if (spender != src && spenderAllowance != uint96(-1)) {\n uint96 newAllowance = sub96(\n spenderAllowance,\n amount,\n \"XVS::transferFrom: transfer amount exceeds spender allowance\"\n );\n allowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n }\n\n _transferTokens(src, dst, amount);\n return true;\n }\n\n /**\n * @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The address to delegate votes to\n */\n function delegate(address delegatee) public validLock {\n return _delegate(msg.sender, delegatee);\n }\n\n /**\n * @notice Delegates votes from signatory to `delegatee`\n * @param delegatee The address to delegate votes to\n * @param nonce The contract state required to match the signature\n * @param expiry The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public validLock {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"XVS::delegateBySig: invalid signature\");\n require(nonce == nonces[signatory]++, \"XVS::delegateBySig: invalid nonce\");\n require(now <= expiry, \"XVS::delegateBySig: signature expired\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Gets the current votes balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for `account`\n */\n function getCurrentVotes(address account) external view returns (uint96) {\n uint32 nCheckpoints = numCheckpoints[account];\n return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n /**\n * @notice Determine the prior number of votes for an account as of a block number\n * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.\n * @param account The address of the account to check\n * @param blockNumber The block number to get the vote balance at\n * @return The number of votes the account had as of the given block\n */\n function getPriorVotes(address account, uint blockNumber) public view returns (uint96) {\n require(blockNumber < block.number, \"XVS::getPriorVotes: not yet determined\");\n\n uint32 nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n }\n\n // First check most recent balance\n if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {\n return checkpoints[account][nCheckpoints - 1].votes;\n }\n\n // Next check implicit zero balance\n if (checkpoints[account][0].fromBlock > blockNumber) {\n return 0;\n }\n\n uint32 lower = 0;\n uint32 upper = nCheckpoints - 1;\n while (upper > lower) {\n uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n Checkpoint memory cp = checkpoints[account][center];\n if (cp.fromBlock == blockNumber) {\n return cp.votes;\n } else if (cp.fromBlock < blockNumber) {\n lower = center;\n } else {\n upper = center - 1;\n }\n }\n return checkpoints[account][lower].votes;\n }\n\n function _delegate(address delegator, address delegatee) internal {\n address currentDelegate = delegates[delegator];\n uint96 delegatorBalance = balances[delegator];\n delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _transferTokens(address src, address dst, uint96 amount) internal {\n require(src != address(0), \"XVS::_transferTokens: cannot transfer from the zero address\");\n require(dst != address(0), \"XVS::_transferTokens: cannot transfer to the zero address\");\n\n balances[src] = sub96(balances[src], amount, \"XVS::_transferTokens: transfer amount exceeds balance\");\n balances[dst] = add96(balances[dst], amount, \"XVS::_transferTokens: transfer amount overflows\");\n emit Transfer(src, dst, amount);\n\n _moveDelegates(delegates[src], delegates[dst], amount);\n }\n\n function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {\n if (srcRep != dstRep && amount > 0) {\n if (srcRep != address(0)) {\n uint32 srcRepNum = numCheckpoints[srcRep];\n uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n uint96 srcRepNew = sub96(srcRepOld, amount, \"XVS::_moveVotes: vote amount underflows\");\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint96 dstRepNew = add96(dstRepOld, amount, \"XVS::_moveVotes: vote amount overflows\");\n _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {\n uint32 blockNumber = safe32(block.number, \"XVS::_writeCheckpoint: block number exceeds 32 bits\");\n\n if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {\n checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n } else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);\n numCheckpoints[delegatee] = nCheckpoints + 1;\n }\n\n emit DelegateVotesChanged(delegatee, oldVotes, newVotes);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n < 2 ** 32, errorMessage);\n return uint32(n);\n }\n\n function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {\n require(n < 2 ** 96, errorMessage);\n return uint96(n);\n }\n\n function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n uint96 c = a + b;\n require(c >= a, errorMessage);\n return c;\n }\n\n function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n function getChainId() internal pure returns (uint) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n return chainId;\n }\n}\n" + }, + "contracts/Tokens/XVS/XVSVesting.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/IBEP20.sol\";\nimport \"../../Utils/SafeBEP20.sol\";\nimport \"./XVSVestingStorage.sol\";\nimport \"./XVSVestingProxy.sol\";\n\n/**\n * @title Venus's XVSVesting Contract\n * @author Venus\n */\ncontract XVSVesting is XVSVestingStorage {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice total vesting period for 1 year in seconds\n uint256 public constant TOTAL_VESTING_TIME = 365 * 24 * 60 * 60;\n\n /// @notice decimal precision for XVS\n uint256 public constant xvsDecimalsMultiplier = 1e18;\n\n /// @notice Emitted when XVSVested is claimed by recipient\n event VestedTokensClaimed(address recipient, uint256 amountClaimed);\n\n /// @notice Emitted when vrtConversionAddress is set\n event VRTConversionSet(address vrtConversionAddress);\n\n /// @notice Emitted when XVS is deposited for vesting\n event XVSVested(address indexed recipient, uint256 startTime, uint256 amount, uint256 withdrawnAmount);\n\n /// @notice Emitted when XVS is withdrawn by recipient\n event XVSWithdrawn(address recipient, uint256 amount);\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n constructor() public {}\n\n /**\n * @notice initialize XVSVestingStorage\n * @param _xvsAddress The XVSToken address\n */\n function initialize(address _xvsAddress) public {\n require(msg.sender == admin, \"only admin may initialize the XVSVesting\");\n require(initialized == false, \"XVSVesting is already initialized\");\n require(_xvsAddress != address(0), \"_xvsAddress cannot be Zero\");\n xvs = IBEP20(_xvsAddress);\n\n _notEntered = true;\n initialized = true;\n }\n\n modifier isInitialized() {\n require(initialized == true, \"XVSVesting is not initialized\");\n _;\n }\n\n /**\n * @notice sets VRTConverter Address\n * @dev Note: If VRTConverter is not set, then Vesting is not allowed\n * @param _vrtConversionAddress The VRTConverterProxy Address\n */\n function setVRTConverter(address _vrtConversionAddress) public {\n require(msg.sender == admin, \"only admin may initialize the Vault\");\n require(_vrtConversionAddress != address(0), \"vrtConversionAddress cannot be Zero\");\n vrtConversionAddress = _vrtConversionAddress;\n emit VRTConversionSet(_vrtConversionAddress);\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n modifier onlyVrtConverter() {\n require(msg.sender == vrtConversionAddress, \"only VRTConversion Address can call the function\");\n _;\n }\n\n modifier vestingExistCheck(address recipient) {\n require(vestings[recipient].length > 0, \"recipient doesnot have any vestingRecord\");\n _;\n }\n\n /**\n * @notice Deposit XVS for Vesting\n * @param recipient The vesting recipient\n * @param depositAmount XVS amount for deposit\n */\n function deposit(\n address recipient,\n uint depositAmount\n ) external isInitialized onlyVrtConverter nonZeroAddress(recipient) {\n require(depositAmount > 0, \"Deposit amount must be non-zero\");\n\n VestingRecord[] storage vestingsOfRecipient = vestings[recipient];\n\n VestingRecord memory vesting = VestingRecord({\n recipient: recipient,\n startTime: getCurrentTime(),\n amount: depositAmount,\n withdrawnAmount: 0\n });\n\n vestingsOfRecipient.push(vesting);\n\n emit XVSVested(recipient, vesting.startTime, vesting.amount, vesting.withdrawnAmount);\n }\n\n /**\n * @notice Withdraw Vested XVS of recipient\n */\n function withdraw() external isInitialized vestingExistCheck(msg.sender) {\n address recipient = msg.sender;\n VestingRecord[] storage vestingsOfRecipient = vestings[recipient];\n uint256 vestingCount = vestingsOfRecipient.length;\n uint256 totalWithdrawableAmount = 0;\n\n for (uint i = 0; i < vestingCount; ++i) {\n VestingRecord storage vesting = vestingsOfRecipient[i];\n (, uint256 toWithdraw) = calculateWithdrawableAmount(\n vesting.amount,\n vesting.startTime,\n vesting.withdrawnAmount\n );\n if (toWithdraw > 0) {\n totalWithdrawableAmount = totalWithdrawableAmount.add(toWithdraw);\n vesting.withdrawnAmount = vesting.withdrawnAmount.add(toWithdraw);\n }\n }\n\n if (totalWithdrawableAmount > 0) {\n uint256 xvsBalance = xvs.balanceOf(address(this));\n require(xvsBalance >= totalWithdrawableAmount, \"Insufficient XVS for withdrawal\");\n emit XVSWithdrawn(recipient, totalWithdrawableAmount);\n xvs.safeTransfer(recipient, totalWithdrawableAmount);\n }\n }\n\n /**\n * @notice get Withdrawable XVS Amount\n * @param recipient The vesting recipient\n * @dev returns A tuple with totalWithdrawableAmount , totalVestedAmount and totalWithdrawnAmount\n */\n function getWithdrawableAmount(\n address recipient\n )\n public\n view\n isInitialized\n nonZeroAddress(recipient)\n vestingExistCheck(recipient)\n returns (uint256 totalWithdrawableAmount, uint256 totalVestedAmount, uint256 totalWithdrawnAmount)\n {\n VestingRecord[] storage vestingsOfRecipient = vestings[recipient];\n uint256 vestingCount = vestingsOfRecipient.length;\n\n for (uint i = 0; i < vestingCount; i++) {\n VestingRecord storage vesting = vestingsOfRecipient[i];\n (uint256 vestedAmount, uint256 toWithdraw) = calculateWithdrawableAmount(\n vesting.amount,\n vesting.startTime,\n vesting.withdrawnAmount\n );\n totalVestedAmount = totalVestedAmount.add(vestedAmount);\n totalWithdrawableAmount = totalWithdrawableAmount.add(toWithdraw);\n totalWithdrawnAmount = totalWithdrawnAmount.add(vesting.withdrawnAmount);\n }\n\n return (totalWithdrawableAmount, totalVestedAmount, totalWithdrawnAmount);\n }\n\n /**\n * @notice get Withdrawable XVS Amount\n * @param amount Amount deposited for vesting\n * @param vestingStartTime time in epochSeconds at the time of vestingDeposit\n * @param withdrawnAmount XVSAmount withdrawn from VestedAmount\n * @dev returns A tuple with vestedAmount and withdrawableAmount\n */\n function calculateWithdrawableAmount(\n uint256 amount,\n uint256 vestingStartTime,\n uint256 withdrawnAmount\n ) internal view returns (uint256, uint256) {\n uint256 vestedAmount = calculateVestedAmount(amount, vestingStartTime, getCurrentTime());\n uint toWithdraw = vestedAmount.sub(withdrawnAmount);\n return (vestedAmount, toWithdraw);\n }\n\n /**\n * @notice calculate total vested amount\n * @param vestingAmount Amount deposited for vesting\n * @param vestingStartTime time in epochSeconds at the time of vestingDeposit\n * @param currentTime currentTime in epochSeconds\n * @return Total XVS amount vested\n */\n function calculateVestedAmount(\n uint256 vestingAmount,\n uint256 vestingStartTime,\n uint256 currentTime\n ) internal view returns (uint256) {\n if (currentTime < vestingStartTime) {\n return 0;\n } else if (currentTime > vestingStartTime.add(TOTAL_VESTING_TIME)) {\n return vestingAmount;\n } else {\n return (vestingAmount.mul(currentTime.sub(vestingStartTime))).div(TOTAL_VESTING_TIME);\n }\n }\n\n /**\n * @notice current block timestamp\n * @return blocktimestamp\n */\n function getCurrentTime() public view returns (uint256) {\n return block.timestamp;\n }\n\n /*** Admin Functions ***/\n function _become(XVSVestingProxy xvsVestingProxy) public {\n require(msg.sender == xvsVestingProxy.admin(), \"only proxy admin can change brains\");\n xvsVestingProxy._acceptImplementation();\n }\n}\n" + }, + "contracts/Tokens/XVS/XVSVestingProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./XVSVestingStorage.sol\";\n\ncontract XVSVestingProxy is XVSVestingAdminStorage {\n /**\n * @notice Emitted when pendingImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingImplementation is accepted, which means XVSVesting implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor(\n address implementation_,\n address _xvsAddress\n ) public nonZeroAddress(implementation_) nonZeroAddress(_xvsAddress) {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_);\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(implementation_, abi.encodeWithSignature(\"initialize(address)\", _xvsAddress));\n }\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n */\n function _setImplementation(address implementation_) public {\n require(msg.sender == admin, \"XVSVestingProxy::_setImplementation: admin only\");\n require(implementation_ != address(0), \"XVSVestingProxy::_setImplementation: invalid implementation address\");\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal nonZeroAddress(callee) returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(\n address newPendingImplementation\n ) public nonZeroAddress(newPendingImplementation) {\n require(msg.sender == admin, \"Only admin can set Pending Implementation\");\n\n address oldPendingImplementation = pendingImplementation;\n\n pendingImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Accepts new implementation of VRT Vault. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n */\n function _acceptImplementation() public {\n // Check caller is pendingImplementation\n require(\n msg.sender == pendingImplementation,\n \"only address marked as pendingImplementation can accept Implementation\"\n );\n\n // Save current values for inclusion in log\n address oldImplementation = implementation;\n address oldPendingImplementation = pendingImplementation;\n\n implementation = pendingImplementation;\n\n pendingImplementation = address(0);\n\n emit NewImplementation(oldImplementation, implementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n */\n function _setPendingAdmin(address newPendingAdmin) public nonZeroAddress(newPendingAdmin) {\n // Check caller = admin\n require(msg.sender == admin, \"only admin can set pending admin\");\n require(newPendingAdmin != pendingAdmin, \"New pendingAdmin can not be same as the previous one\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n */\n function _acceptAdmin() public {\n // Check caller is pendingAdmin\n require(msg.sender == pendingAdmin, \"only address marked as pendingAdmin can accept as Admin\");\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/Tokens/XVS/XVSVestingStorage.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/SafeMath.sol\";\nimport \"../../Utils/IBEP20.sol\";\n\ncontract XVSVestingAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of XVSVesting\n */\n address public implementation;\n\n /**\n * @notice Pending brains of XVSVesting\n */\n address public pendingImplementation;\n}\n\ncontract XVSVestingStorage is XVSVestingAdminStorage {\n struct VestingRecord {\n address recipient;\n uint256 startTime;\n uint256 amount;\n uint256 withdrawnAmount;\n }\n\n /// @notice Guard variable for re-entrancy checks\n bool public _notEntered;\n\n /// @notice indicator to check if the contract is initialized\n bool public initialized;\n\n /// @notice The XVS TOKEN!\n IBEP20 public xvs;\n\n /// @notice VRTConversion Contract Address\n address public vrtConversionAddress;\n\n /// @notice mapping of VestingRecord(s) for user(s)\n mapping(address => VestingRecord[]) public vestings;\n}\n" + }, + "contracts/Utils/Address.sol": { + "content": "pragma solidity ^0.5.5;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n codehash := extcodehash(account)\n }\n return (codehash != accountHash && codehash != 0x0);\n }\n\n /**\n * @dev Converts an `address` into `address payable`. Note that this is\n * simply a type cast: the actual underlying value is not changed.\n *\n * _Available since v2.4.0._\n */\n function toPayable(address account) internal pure returns (address payable) {\n return address(uint160(account));\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n *\n * _Available since v2.4.0._\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-call-value\n // solium-disable-next-line security/no-call-value\n (bool success, ) = recipient.call.value(amount)(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/Utils/CarefulMath.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title Careful Math\n * @author Venus\n * @notice Derived from OpenZeppelin's SafeMath library\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\n */\ncontract CarefulMath {\n /**\n * @dev Possible error codes that we can return\n */\n enum MathError {\n NO_ERROR,\n DIVISION_BY_ZERO,\n INTEGER_OVERFLOW,\n INTEGER_UNDERFLOW\n }\n\n /**\n * @dev Multiplies two numbers, returns an error on overflow.\n */\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\n if (a == 0) {\n return (MathError.NO_ERROR, 0);\n }\n\n uint c = a * b;\n\n if (c / a != b) {\n return (MathError.INTEGER_OVERFLOW, 0);\n } else {\n return (MathError.NO_ERROR, c);\n }\n }\n\n /**\n * @dev Integer division of two numbers, truncating the quotient.\n */\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\n if (b == 0) {\n return (MathError.DIVISION_BY_ZERO, 0);\n }\n\n return (MathError.NO_ERROR, a / b);\n }\n\n /**\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\n */\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\n if (b <= a) {\n return (MathError.NO_ERROR, a - b);\n } else {\n return (MathError.INTEGER_UNDERFLOW, 0);\n }\n }\n\n /**\n * @dev Adds two numbers, returns an error on overflow.\n */\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\n uint c = a + b;\n\n if (c >= a) {\n return (MathError.NO_ERROR, c);\n } else {\n return (MathError.INTEGER_OVERFLOW, 0);\n }\n }\n\n /**\n * @dev add a and b and then subtract c\n */\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\n (MathError err0, uint sum) = addUInt(a, b);\n\n if (err0 != MathError.NO_ERROR) {\n return (err0, 0);\n }\n\n return subUInt(sum, c);\n }\n}\n" + }, + "contracts/Utils/Context.sol": { + "content": "pragma solidity ^0.5.16;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\ncontract Context {\n // Empty internal constructor, to prevent people from mistakenly deploying\n // an instance of this contract, which should be used via inheritance.\n constructor() internal {}\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "contracts/Utils/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// Adapted from OpenZeppelin Contracts v4.3.2 (utils/cryptography/ECDSA.sol)\n\n// SPDX-Copyright-Text: OpenZeppelin, 2021\n// SPDX-Copyright-Text: Venus, 2021\n\npragma solidity ^0.5.16;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\ncontract ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n}\n" + }, + "contracts/Utils/ErrorReporter.sol": { + "content": "pragma solidity ^0.5.16;\n\ncontract ComptrollerErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED,\n COMPTROLLER_MISMATCH,\n INSUFFICIENT_SHORTFALL,\n INSUFFICIENT_LIQUIDITY,\n INVALID_CLOSE_FACTOR,\n INVALID_COLLATERAL_FACTOR,\n INVALID_LIQUIDATION_INCENTIVE,\n MARKET_NOT_ENTERED, // no longer possible\n MARKET_NOT_LISTED,\n MARKET_ALREADY_LISTED,\n MATH_ERROR,\n NONZERO_BORROW_BALANCE,\n PRICE_ERROR,\n REJECTION,\n SNAPSHOT_ERROR,\n TOO_MANY_ASSETS,\n TOO_MUCH_REPAY,\n INSUFFICIENT_BALANCE_FOR_VAI,\n MARKET_NOT_COLLATERAL\n }\n\n enum FailureInfo {\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n EXIT_MARKET_BALANCE_OWED,\n EXIT_MARKET_REJECTION,\n SET_CLOSE_FACTOR_OWNER_CHECK,\n SET_CLOSE_FACTOR_VALIDATION,\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\n SET_COLLATERAL_FACTOR_NO_EXISTS,\n SET_COLLATERAL_FACTOR_VALIDATION,\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\n SET_IMPLEMENTATION_OWNER_CHECK,\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\n SET_MAX_ASSETS_OWNER_CHECK,\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\n SET_PRICE_ORACLE_OWNER_CHECK,\n SUPPORT_MARKET_EXISTS,\n SUPPORT_MARKET_OWNER_CHECK,\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\n SET_VAI_MINT_RATE_CHECK,\n SET_VAICONTROLLER_OWNER_CHECK,\n SET_MINTED_VAI_REJECTION,\n SET_TREASURY_OWNER_CHECK,\n UNLIST_MARKET_NOT_LISTED\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n\ncontract TokenErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED,\n BAD_INPUT,\n COMPTROLLER_REJECTION,\n COMPTROLLER_CALCULATION_ERROR,\n INTEREST_RATE_MODEL_ERROR,\n INVALID_ACCOUNT_PAIR,\n INVALID_CLOSE_AMOUNT_REQUESTED,\n INVALID_COLLATERAL_FACTOR,\n MATH_ERROR,\n MARKET_NOT_FRESH,\n MARKET_NOT_LISTED,\n TOKEN_INSUFFICIENT_ALLOWANCE,\n TOKEN_INSUFFICIENT_BALANCE,\n TOKEN_INSUFFICIENT_CASH,\n TOKEN_TRANSFER_IN_FAILED,\n TOKEN_TRANSFER_OUT_FAILED,\n TOKEN_PRICE_ERROR\n }\n\n /*\n * Note: FailureInfo (but not Error) is kept in alphabetical order\n * This is because FailureInfo grows significantly faster, and\n * the order of Error has some meaning, while the order of FailureInfo\n * is entirely arbitrary.\n */\n enum FailureInfo {\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\n BORROW_ACCRUE_INTEREST_FAILED,\n BORROW_CASH_NOT_AVAILABLE,\n BORROW_FRESHNESS_CHECK,\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\n BORROW_MARKET_NOT_LISTED,\n BORROW_COMPTROLLER_REJECTION,\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\n LIQUIDATE_COMPTROLLER_REJECTION,\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\n LIQUIDATE_FRESHNESS_CHECK,\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\n LIQUIDATE_SEIZE_TOO_MUCH,\n MINT_ACCRUE_INTEREST_FAILED,\n MINT_COMPTROLLER_REJECTION,\n MINT_EXCHANGE_CALCULATION_FAILED,\n MINT_EXCHANGE_RATE_READ_FAILED,\n MINT_FRESHNESS_CHECK,\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\n MINT_TRANSFER_IN_FAILED,\n MINT_TRANSFER_IN_NOT_POSSIBLE,\n REDEEM_ACCRUE_INTEREST_FAILED,\n REDEEM_COMPTROLLER_REJECTION,\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\n REDEEM_EXCHANGE_RATE_READ_FAILED,\n REDEEM_FRESHNESS_CHECK,\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\n REDUCE_RESERVES_ADMIN_CHECK,\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\n REDUCE_RESERVES_FRESH_CHECK,\n REDUCE_RESERVES_VALIDATION,\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\n REPAY_BORROW_COMPTROLLER_REJECTION,\n REPAY_BORROW_FRESHNESS_CHECK,\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\n SET_COLLATERAL_FACTOR_VALIDATION,\n SET_COMPTROLLER_OWNER_CHECK,\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\n SET_MAX_ASSETS_OWNER_CHECK,\n SET_ORACLE_MARKET_NOT_LISTED,\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\n SET_RESERVE_FACTOR_ADMIN_CHECK,\n SET_RESERVE_FACTOR_FRESH_CHECK,\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\n TRANSFER_COMPTROLLER_REJECTION,\n TRANSFER_NOT_ALLOWED,\n TRANSFER_NOT_ENOUGH,\n TRANSFER_TOO_MUCH,\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\n ADD_RESERVES_FRESH_CHECK,\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\n REPAY_VAI_COMPTROLLER_REJECTION,\n REPAY_VAI_FRESHNESS_CHECK,\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n\ncontract VAIControllerErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED, // The sender is not authorized to perform this action.\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\n MATH_ERROR, // A math calculation error occurred.\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\n }\n\n enum FailureInfo {\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\n SET_COMPTROLLER_OWNER_CHECK,\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n VAI_MINT_REJECTION,\n VAI_BURN_REJECTION,\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\n VAI_LIQUIDATE_FRESHNESS_CHECK,\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\n MINT_FEE_CALCULATION_FAILED,\n SET_TREASURY_OWNER_CHECK\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n" + }, + "contracts/Utils/Exponential.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./CarefulMath.sol\";\nimport \"./ExponentialNoError.sol\";\n\n/**\n * @title Exponential module for storing fixed-precision decimals\n * @author Venus\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\n * `Exp({mantissa: 5100000000000000000})`.\n */\ncontract Exponential is CarefulMath, ExponentialNoError {\n /**\n * @dev Creates an exponential from numerator and denominator values.\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\n * or if `denom` is zero.\n */\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\n if (err1 != MathError.NO_ERROR) {\n return (err1, Exp({ mantissa: 0 }));\n }\n\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\n }\n\n /**\n * @dev Adds two exponentials, returning a new exponential.\n */\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\n\n return (error, Exp({ mantissa: result }));\n }\n\n /**\n * @dev Subtracts two exponentials, returning a new exponential.\n */\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\n\n return (error, Exp({ mantissa: result }));\n }\n\n /**\n * @dev Multiply an Exp by a scalar, returning a new Exp.\n */\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\n }\n\n /**\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\n */\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\n (MathError err, Exp memory product) = mulScalar(a, scalar);\n if (err != MathError.NO_ERROR) {\n return (err, 0);\n }\n\n return (MathError.NO_ERROR, truncate(product));\n }\n\n /**\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\n */\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\n (MathError err, Exp memory product) = mulScalar(a, scalar);\n if (err != MathError.NO_ERROR) {\n return (err, 0);\n }\n\n return addUInt(truncate(product), addend);\n }\n\n /**\n * @dev Divide an Exp by a scalar, returning a new Exp.\n */\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\n }\n\n /**\n * @dev Divide a scalar by an Exp, returning a new Exp.\n */\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\n /*\n We are doing this as:\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\n\n How it works:\n Exp = a / b;\n Scalar = s;\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\n */\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n return getExp(numerator, divisor.mantissa);\n }\n\n /**\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\n */\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\n if (err != MathError.NO_ERROR) {\n return (err, 0);\n }\n\n return (MathError.NO_ERROR, truncate(fraction));\n }\n\n /**\n * @dev Multiplies two exponentials, returning a new exponential.\n */\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n\n // We add half the scale before dividing so that we get rounding instead of truncation.\n // See \"Listing 6\" and text above it at https://accu.org/index.php/journals/1717\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\n if (err1 != MathError.NO_ERROR) {\n return (err1, Exp({ mantissa: 0 }));\n }\n\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\n assert(err2 == MathError.NO_ERROR);\n\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\n }\n\n /**\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\n */\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\n }\n\n /**\n * @dev Multiplies three exponentials, returning a new exponential.\n */\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\n (MathError err, Exp memory ab) = mulExp(a, b);\n if (err != MathError.NO_ERROR) {\n return (err, ab);\n }\n return mulExp(ab, c);\n }\n\n /**\n * @dev Divides two exponentials, returning a new exponential.\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\n */\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\n return getExp(a.mantissa, b.mantissa);\n }\n}\n" + }, + "contracts/Utils/ExponentialNoError.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title Exponential module for storing fixed-precision decimals\n * @author Compound\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\n * `Exp({mantissa: 5100000000000000000})`.\n */\ncontract ExponentialNoError {\n uint internal constant expScale = 1e18;\n uint internal constant doubleScale = 1e36;\n uint internal constant halfExpScale = expScale / 2;\n uint internal constant mantissaOne = expScale;\n\n struct Exp {\n uint mantissa;\n }\n\n struct Double {\n uint mantissa;\n }\n\n /**\n * @dev Truncates the given exp to a whole number value.\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\n */\n function truncate(Exp memory exp) internal pure returns (uint) {\n // Note: We are not using careful math here as we're performing a division that cannot fail\n return exp.mantissa / expScale;\n }\n\n /**\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\n */\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\n Exp memory product = mul_(a, scalar);\n return truncate(product);\n }\n\n /**\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\n */\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\n Exp memory product = mul_(a, scalar);\n return add_(truncate(product), addend);\n }\n\n /**\n * @dev Checks if first Exp is less than second Exp.\n */\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\n return left.mantissa < right.mantissa;\n }\n\n /**\n * @dev Checks if left Exp <= right Exp.\n */\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\n return left.mantissa <= right.mantissa;\n }\n\n /**\n * @dev Checks if left Exp > right Exp.\n */\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\n return left.mantissa > right.mantissa;\n }\n\n /**\n * @dev returns true if Exp is exactly zero\n */\n function isZeroExp(Exp memory value) internal pure returns (bool) {\n return value.mantissa == 0;\n }\n\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\n require(n < 2 ** 224, errorMessage);\n return uint224(n);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n < 2 ** 32, errorMessage);\n return uint32(n);\n }\n\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\n }\n\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\n }\n\n function add_(uint a, uint b) internal pure returns (uint) {\n return add_(a, b, \"addition overflow\");\n }\n\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\n uint c = a + b;\n require(c >= a, errorMessage);\n return c;\n }\n\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\n }\n\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\n }\n\n function sub_(uint a, uint b) internal pure returns (uint) {\n return sub_(a, b, \"subtraction underflow\");\n }\n\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\n }\n\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\n return mul_(a, b.mantissa) / expScale;\n }\n\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\n }\n\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint a, Double memory b) internal pure returns (uint) {\n return mul_(a, b.mantissa) / doubleScale;\n }\n\n function mul_(uint a, uint b) internal pure returns (uint) {\n return mul_(a, b, \"multiplication overflow\");\n }\n\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\n if (a == 0 || b == 0) {\n return 0;\n }\n uint c = a * b;\n require(c / a == b, errorMessage);\n return c;\n }\n\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\n }\n\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint a, Exp memory b) internal pure returns (uint) {\n return div_(mul_(a, expScale), b.mantissa);\n }\n\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\n }\n\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint a, Double memory b) internal pure returns (uint) {\n return div_(mul_(a, doubleScale), b.mantissa);\n }\n\n function div_(uint a, uint b) internal pure returns (uint) {\n return div_(a, b, \"divide by zero\");\n }\n\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n function fraction(uint a, uint b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\n }\n}\n" + }, + "contracts/Utils/IBEP20.sol": { + "content": "pragma solidity ^0.5.0;\n\n/**\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {BEP20Detailed}.\n */\ninterface IBEP20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "contracts/Utils/Ownable.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "contracts/Utils/Owned.sol": { + "content": "pragma solidity ^0.5.16;\n\ncontract Owned {\n address public owner;\n\n event OwnershipTransferred(address indexed _from, address indexed _to);\n\n constructor() public {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Should be owner\");\n _;\n }\n\n function transferOwnership(address newOwner) public onlyOwner {\n owner = newOwner;\n emit OwnershipTransferred(owner, newOwner);\n }\n}\n" + }, + "contracts/Utils/SafeBEP20.sol": { + "content": "pragma solidity ^0.5.0;\n\nimport \"./SafeMath.sol\";\nimport \"./IBEP20.sol\";\nimport \"./Address.sol\";\n\n/**\n * @title SafeBEP20\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeBEP20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeBEP20: approve from non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(\n value,\n \"SafeBEP20: decreased allowance below zero\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeBEP20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeBEP20: low-level call failed\");\n\n if (returndata.length > 0) {\n // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeBEP20: BEP20 operation did not succeed\");\n }\n }\n}\n" + }, + "contracts/Utils/SafeCast.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2 ** 128, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2 ** 64, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2 ** 32, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2 ** 16, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2 ** 8, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2 ** 127 && value < 2 ** 127, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2 ** 63 && value < 2 ** 63, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2 ** 31 && value < 2 ** 31, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2 ** 15 && value < 2 ** 15, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2 ** 7 && value < 2 ** 7, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2 ** 255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/Utils/SafeMath.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return add(a, b, \"SafeMath: addition overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, errorMessage);\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/Utils/Tokenlock.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./Owned.sol\";\n\ncontract Tokenlock is Owned {\n /// @notice Indicates if token is locked\n uint8 internal isLocked = 0;\n\n event Freezed();\n event UnFreezed();\n\n modifier validLock() {\n require(isLocked == 0, \"Token is locked\");\n _;\n }\n\n function freeze() public onlyOwner {\n isLocked = 1;\n\n emit Freezed();\n }\n\n function unfreeze() public onlyOwner {\n isLocked = 0;\n\n emit UnFreezed();\n }\n}\n" + }, + "contracts/VAIVault/VAIVault.sol": { + "content": "pragma solidity 0.5.16;\n\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/IBEP20.sol\";\nimport \"./VAIVaultStorage.sol\";\nimport \"./VAIVaultErrorReporter.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV5.sol\";\nimport { VAIVaultProxy } from \"./VAIVaultProxy.sol\";\n\n/**\n * @title VAI Vault\n * @author Venus\n * @notice The VAI Vault is configured for users to stake VAI And receive XVS as a reward.\n */\ncontract VAIVault is VAIVaultStorage, AccessControlledV5 {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice Event emitted when VAI deposit\n event Deposit(address indexed user, uint256 amount);\n\n /// @notice Event emitted when VAI withrawal\n event Withdraw(address indexed user, uint256 amount);\n\n /// @notice Event emitted when vault is paused\n event VaultPaused(address indexed admin);\n\n /// @notice Event emitted when vault is resumed after pause\n event VaultResumed(address indexed admin);\n\n constructor() public {\n admin = msg.sender;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n /*** Reentrancy Guard ***/\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n /**\n * @dev Prevents functions to execute when vault is paused.\n */\n modifier isActive() {\n require(!vaultPaused, \"Vault is paused\");\n _;\n }\n\n /**\n * @notice Pause vault\n */\n function pause() external {\n _checkAccessAllowed(\"pause()\");\n require(!vaultPaused, \"Vault is already paused\");\n vaultPaused = true;\n emit VaultPaused(msg.sender);\n }\n\n /**\n * @notice Resume vault\n */\n function resume() external {\n _checkAccessAllowed(\"resume()\");\n require(vaultPaused, \"Vault is not paused\");\n vaultPaused = false;\n emit VaultResumed(msg.sender);\n }\n\n /**\n * @notice Deposit VAI to VAIVault for XVS allocation\n * @param _amount The amount to deposit to vault\n */\n function deposit(uint256 _amount) external nonReentrant isActive {\n UserInfo storage user = userInfo[msg.sender];\n\n updateVault();\n\n // Transfer pending tokens to user\n updateAndPayOutPending(msg.sender);\n\n // Transfer in the amounts from user\n if (_amount > 0) {\n vai.safeTransferFrom(address(msg.sender), address(this), _amount);\n user.amount = user.amount.add(_amount);\n }\n\n user.rewardDebt = user.amount.mul(accXVSPerShare).div(1e18);\n emit Deposit(msg.sender, _amount);\n }\n\n /**\n * @notice Withdraw VAI from VAIVault\n * @param _amount The amount to withdraw from vault\n */\n function withdraw(uint256 _amount) external nonReentrant isActive {\n _withdraw(msg.sender, _amount);\n }\n\n /**\n * @notice Claim XVS from VAIVault\n */\n function claim() external nonReentrant isActive {\n _withdraw(msg.sender, 0);\n }\n\n /**\n * @notice Claim XVS from VAIVault\n * @param account The account for which to claim XVS\n */\n function claim(address account) external nonReentrant isActive {\n _withdraw(account, 0);\n }\n\n /**\n * @notice Low level withdraw function\n * @param account The account to withdraw from vault\n * @param _amount The amount to withdraw from vault\n */\n function _withdraw(address account, uint256 _amount) internal {\n UserInfo storage user = userInfo[account];\n require(user.amount >= _amount, \"withdraw: not good\");\n\n updateVault();\n updateAndPayOutPending(account); // Update balances of account this is not withdrawal but claiming XVS farmed\n\n if (_amount > 0) {\n user.amount = user.amount.sub(_amount);\n vai.safeTransfer(address(account), _amount);\n }\n user.rewardDebt = user.amount.mul(accXVSPerShare).div(1e18);\n\n emit Withdraw(account, _amount);\n }\n\n /**\n * @notice View function to see pending XVS on frontend\n * @param _user The user to see pending XVS\n * @return Amount of XVS the user can claim\n */\n function pendingXVS(address _user) public view returns (uint256) {\n UserInfo storage user = userInfo[_user];\n\n return user.amount.mul(accXVSPerShare).div(1e18).sub(user.rewardDebt);\n }\n\n /**\n * @notice Update and pay out pending XVS to user\n * @param account The user to pay out\n */\n function updateAndPayOutPending(address account) internal {\n uint256 pending = pendingXVS(account);\n\n if (pending > 0) {\n safeXVSTransfer(account, pending);\n }\n }\n\n /**\n * @notice Safe XVS transfer function, just in case if rounding error causes pool to not have enough XVS\n * @param _to The address that XVS to be transfered\n * @param _amount The amount that XVS to be transfered\n */\n function safeXVSTransfer(address _to, uint256 _amount) internal {\n uint256 xvsBal = xvs.balanceOf(address(this));\n\n if (_amount > xvsBal) {\n xvs.transfer(_to, xvsBal);\n xvsBalance = xvs.balanceOf(address(this));\n } else {\n xvs.transfer(_to, _amount);\n xvsBalance = xvs.balanceOf(address(this));\n }\n }\n\n /**\n * @notice Function that updates pending rewards\n */\n function updatePendingRewards() public isActive {\n uint256 newRewards = xvs.balanceOf(address(this)).sub(xvsBalance);\n\n if (newRewards > 0) {\n xvsBalance = xvs.balanceOf(address(this)); // If there is no change the balance didn't change\n pendingRewards = pendingRewards.add(newRewards);\n }\n }\n\n /**\n * @notice Update reward variables to be up-to-date\n */\n function updateVault() internal {\n updatePendingRewards();\n\n uint256 vaiBalance = vai.balanceOf(address(this));\n if (vaiBalance == 0) {\n // avoids division by 0 errors\n return;\n }\n\n accXVSPerShare = accXVSPerShare.add(pendingRewards.mul(1e18).div(vaiBalance));\n pendingRewards = 0;\n }\n\n /*** Admin Functions ***/\n\n function _become(VAIVaultProxy vaiVaultProxy) external {\n require(msg.sender == vaiVaultProxy.admin(), \"only proxy admin can change brains\");\n require(vaiVaultProxy._acceptImplementation() == 0, \"change not authorized\");\n }\n\n function setVenusInfo(address _xvs, address _vai) external onlyAdmin {\n require(_xvs != address(0) && _vai != address(0), \"addresses must not be zero\");\n require(address(xvs) == address(0) && address(vai) == address(0), \"addresses already set\");\n xvs = IBEP20(_xvs);\n vai = IBEP20(_vai);\n\n _notEntered = true;\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlAddress New address for the access control\n */\n function setAccessControl(address newAccessControlAddress) external onlyAdmin {\n _setAccessControlManager(newAccessControlAddress);\n }\n}\n" + }, + "contracts/VAIVault/VAIVaultErrorReporter.sol": { + "content": "pragma solidity ^0.5.16;\n\ncontract VAIVaultErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED\n }\n\n enum FailureInfo {\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n" + }, + "contracts/VAIVault/VAIVaultProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VAIVaultStorage.sol\";\nimport \"./VAIVaultErrorReporter.sol\";\n\n/**\n * @title VAI Vault Proxy\n * @author Venus\n * @notice Proxy contract for the VAI Vault\n */\ncontract VAIVaultProxy is VAIVaultAdminStorage, VAIVaultErrorReporter {\n /**\n * @notice Emitted when pendingVAIVaultImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingVAIVaultImplementation is accepted, which means VAI Vault implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor() public {\n // Set admin to caller\n admin = msg.sender;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public returns (uint) {\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK);\n }\n\n address oldPendingImplementation = pendingVAIVaultImplementation;\n\n pendingVAIVaultImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingVAIVaultImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts new implementation of VAI Vault. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public returns (uint) {\n // Check caller is pendingImplementation\n if (msg.sender != pendingVAIVaultImplementation) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldImplementation = vaiVaultImplementation;\n address oldPendingImplementation = pendingVAIVaultImplementation;\n\n vaiVaultImplementation = pendingVAIVaultImplementation;\n\n pendingVAIVaultImplementation = address(0);\n\n emit NewImplementation(oldImplementation, vaiVaultImplementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingVAIVaultImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public returns (uint) {\n // Check caller = admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK);\n }\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public returns (uint) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = vaiVaultImplementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/VAIVault/VAIVaultStorage.sol": { + "content": "pragma solidity ^0.5.16;\nimport \"../Utils/SafeMath.sol\";\nimport \"../Utils/IBEP20.sol\";\n\ncontract VAIVaultAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of VAI Vault\n */\n address public vaiVaultImplementation;\n\n /**\n * @notice Pending brains of VAI Vault\n */\n address public pendingVAIVaultImplementation;\n}\n\ncontract VAIVaultStorage is VAIVaultAdminStorage {\n /// @notice The XVS TOKEN!\n IBEP20 public xvs;\n\n /// @notice The VAI TOKEN!\n IBEP20 public vai;\n\n /// @notice Guard variable for re-entrancy checks\n bool internal _notEntered;\n\n /// @notice XVS balance of vault\n uint256 public xvsBalance;\n\n /// @notice Accumulated XVS per share\n uint256 public accXVSPerShare;\n\n //// pending rewards awaiting anyone to update\n uint256 public pendingRewards;\n\n /// @notice Info of each user.\n struct UserInfo {\n uint256 amount;\n uint256 rewardDebt;\n }\n\n // Info of each user that stakes tokens.\n mapping(address => UserInfo) public userInfo;\n\n /// @notice pause indicator for Vault\n bool public vaultPaused;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/VRTVault/VRTVault.sol": { + "content": "pragma solidity 0.5.16;\n\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/IBEP20.sol\";\nimport \"./VRTVaultStorage.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV5.sol\";\n\ninterface IVRTVaultProxy {\n function _acceptImplementation() external;\n\n function admin() external returns (address);\n}\n\ncontract VRTVault is VRTVaultStorage, AccessControlledV5 {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice The upper bound for lastAccruingBlock. Close to year 3,000, considering 3 seconds per block. Used to avoid a value absurdly high\n uint256 public constant MAX_LAST_ACCRUING_BLOCK = 9999999999;\n\n /// @notice Event emitted when vault is paused\n event VaultPaused(address indexed admin);\n\n /// @notice Event emitted when vault is resumed after pause\n event VaultResumed(address indexed admin);\n\n /// @notice Event emitted on VRT deposit\n event Deposit(address indexed user, uint256 amount);\n\n /// @notice Event emitted when accruedInterest and VRT PrincipalAmount is withrawn\n event Withdraw(\n address indexed user,\n uint256 withdrawnAmount,\n uint256 totalPrincipalAmount,\n uint256 accruedInterest\n );\n\n /// @notice Event emitted when Admin withdraw BEP20 token from contract\n event WithdrawToken(address indexed tokenAddress, address indexed receiver, uint256 amount);\n\n /// @notice Event emitted when accruedInterest is claimed\n event Claim(address indexed user, uint256 interestAmount);\n\n /// @notice Event emitted when lastAccruingBlock state variable changes\n event LastAccruingBlockChanged(uint256 oldLastAccruingBlock, uint256 newLastAccruingBlock);\n\n constructor() public {\n admin = msg.sender;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin allowed\");\n _;\n }\n\n function initialize(address _vrtAddress, uint256 _interestRatePerBlock) public {\n require(msg.sender == admin, \"only admin may initialize the Vault\");\n require(_vrtAddress != address(0), \"vrtAddress cannot be Zero\");\n require(interestRatePerBlock == 0, \"Vault may only be initialized once\");\n\n // Set initial exchange rate\n interestRatePerBlock = _interestRatePerBlock;\n require(interestRatePerBlock > 0, \"interestRate Per Block must be greater than zero.\");\n\n // Set the VRT\n vrt = IBEP20(_vrtAddress);\n _notEntered = true;\n }\n\n modifier isInitialized() {\n require(interestRatePerBlock > 0, \"Vault is not initialized\");\n _;\n }\n\n modifier isActive() {\n require(!vaultPaused, \"Vault is paused\");\n _;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n modifier userHasPosition(address userAddress) {\n UserInfo storage user = userInfo[userAddress];\n require(user.userAddress != address(0), \"User does not have any position in the Vault.\");\n _;\n }\n\n /**\n * @notice Pause vault\n */\n function pause() external {\n _checkAccessAllowed(\"pause()\");\n require(!vaultPaused, \"Vault is already paused\");\n vaultPaused = true;\n emit VaultPaused(msg.sender);\n }\n\n /**\n * @notice Resume vault\n */\n function resume() external {\n _checkAccessAllowed(\"resume()\");\n require(vaultPaused, \"Vault is not paused\");\n vaultPaused = false;\n emit VaultResumed(msg.sender);\n }\n\n /**\n * @notice Deposit VRT to VRTVault for a fixed-interest-rate\n * @param depositAmount The amount to deposit to vault\n */\n function deposit(uint256 depositAmount) external nonReentrant isInitialized isActive {\n require(depositAmount > 0, \"Deposit amount must be non-zero\");\n\n address userAddress = msg.sender;\n UserInfo storage user = userInfo[userAddress];\n\n if (user.userAddress == address(0)) {\n user.userAddress = userAddress;\n user.totalPrincipalAmount = depositAmount;\n } else {\n // accrue Interest and transfer to the user\n uint256 accruedInterest = computeAccruedInterest(user.totalPrincipalAmount, user.accrualStartBlockNumber);\n\n user.totalPrincipalAmount = user.totalPrincipalAmount.add(depositAmount);\n\n if (accruedInterest > 0) {\n uint256 vrtBalance = vrt.balanceOf(address(this));\n require(\n vrtBalance >= accruedInterest,\n \"Failed to transfer accruedInterest, Insufficient VRT in Vault.\"\n );\n emit Claim(userAddress, accruedInterest);\n vrt.safeTransfer(user.userAddress, accruedInterest);\n }\n }\n\n uint256 currentBlock_ = getBlockNumber();\n if (lastAccruingBlock > currentBlock_) {\n user.accrualStartBlockNumber = currentBlock_;\n } else {\n user.accrualStartBlockNumber = lastAccruingBlock;\n }\n emit Deposit(userAddress, depositAmount);\n vrt.safeTransferFrom(userAddress, address(this), depositAmount);\n }\n\n /**\n * @notice get accruedInterest of the user's VRTDeposits in the Vault\n * @param userAddress Address of User in the the Vault\n * @return The interest accrued, in VRT\n */\n function getAccruedInterest(\n address userAddress\n ) public view nonZeroAddress(userAddress) isInitialized returns (uint256) {\n UserInfo storage user = userInfo[userAddress];\n if (user.accrualStartBlockNumber == 0) {\n return 0;\n }\n\n return computeAccruedInterest(user.totalPrincipalAmount, user.accrualStartBlockNumber);\n }\n\n /**\n * @notice get accruedInterest of the user's VRTDeposits in the Vault\n * @param totalPrincipalAmount of the User\n * @param accrualStartBlockNumber of the User\n * @return The interest accrued, in VRT\n */\n function computeAccruedInterest(\n uint256 totalPrincipalAmount,\n uint256 accrualStartBlockNumber\n ) internal view isInitialized returns (uint256) {\n uint256 blockNumber = getBlockNumber();\n uint256 _lastAccruingBlock = lastAccruingBlock;\n\n if (blockNumber > _lastAccruingBlock) {\n blockNumber = _lastAccruingBlock;\n }\n\n if (accrualStartBlockNumber == 0 || accrualStartBlockNumber >= blockNumber) {\n return 0;\n }\n\n // Number of blocks since deposit\n uint256 blockDelta = blockNumber.sub(accrualStartBlockNumber);\n uint256 accruedInterest = (totalPrincipalAmount.mul(interestRatePerBlock).mul(blockDelta)).div(1e18);\n return accruedInterest;\n }\n\n /**\n * @notice claim the accruedInterest of the user's VRTDeposits in the Vault\n */\n function claim() external nonReentrant isInitialized userHasPosition(msg.sender) isActive {\n _claim(msg.sender);\n }\n\n /**\n * @notice claim the accruedInterest of the user's VRTDeposits in the Vault\n * @param account The account for which to claim rewards\n */\n function claim(address account) external nonReentrant isInitialized userHasPosition(account) isActive {\n _claim(account);\n }\n\n /**\n * @notice Low level claim function\n * @param account The account for which to claim rewards\n */\n function _claim(address account) internal {\n uint256 accruedInterest = getAccruedInterest(account);\n if (accruedInterest > 0) {\n UserInfo storage user = userInfo[account];\n uint256 vrtBalance = vrt.balanceOf(address(this));\n require(vrtBalance >= accruedInterest, \"Failed to transfer VRT, Insufficient VRT in Vault.\");\n emit Claim(account, accruedInterest);\n uint256 currentBlock_ = getBlockNumber();\n if (lastAccruingBlock > currentBlock_) {\n user.accrualStartBlockNumber = currentBlock_;\n } else {\n user.accrualStartBlockNumber = lastAccruingBlock;\n }\n vrt.safeTransfer(user.userAddress, accruedInterest);\n }\n }\n\n /**\n * @notice withdraw accruedInterest and totalPrincipalAmount of the user's VRTDeposit in the Vault\n */\n function withdraw() external nonReentrant isInitialized userHasPosition(msg.sender) isActive {\n address userAddress = msg.sender;\n uint256 accruedInterest = getAccruedInterest(userAddress);\n\n UserInfo storage user = userInfo[userAddress];\n\n uint256 totalPrincipalAmount = user.totalPrincipalAmount;\n uint256 vrtForWithdrawal = accruedInterest.add(totalPrincipalAmount);\n user.totalPrincipalAmount = 0;\n user.accrualStartBlockNumber = getBlockNumber();\n\n uint256 vrtBalance = vrt.balanceOf(address(this));\n require(vrtBalance >= vrtForWithdrawal, \"Failed to transfer VRT, Insufficient VRT in Vault.\");\n\n emit Withdraw(userAddress, vrtForWithdrawal, totalPrincipalAmount, accruedInterest);\n vrt.safeTransfer(user.userAddress, vrtForWithdrawal);\n }\n\n /**\n * @notice withdraw BEP20 tokens from the contract to a recipient address.\n * @param tokenAddress address of the BEP20 token\n * @param receiver recipient of the BEP20 token\n * @param amount tokenAmount\n */\n function withdrawBep20(\n address tokenAddress,\n address receiver,\n uint256 amount\n ) external isInitialized nonZeroAddress(tokenAddress) nonZeroAddress(receiver) {\n _checkAccessAllowed(\"withdrawBep20(address,address,uint256)\");\n require(amount > 0, \"amount is invalid\");\n IBEP20 token = IBEP20(tokenAddress);\n require(amount <= token.balanceOf(address(this)), \"Insufficient amount in Vault\");\n emit WithdrawToken(tokenAddress, receiver, amount);\n token.safeTransfer(receiver, amount);\n }\n\n function setLastAccruingBlock(uint256 _lastAccruingBlock) external {\n _checkAccessAllowed(\"setLastAccruingBlock(uint256)\");\n require(_lastAccruingBlock < MAX_LAST_ACCRUING_BLOCK, \"_lastAccruingBlock is absurdly high\");\n\n uint256 oldLastAccruingBlock = lastAccruingBlock;\n uint256 currentBlock = getBlockNumber();\n if (oldLastAccruingBlock != 0) {\n require(currentBlock < oldLastAccruingBlock, \"Cannot change at this point\");\n }\n if (oldLastAccruingBlock == 0 || _lastAccruingBlock < oldLastAccruingBlock) {\n // Must be in future\n require(currentBlock < _lastAccruingBlock, \"Invalid _lastAccruingBlock interest have been accumulated\");\n }\n lastAccruingBlock = _lastAccruingBlock;\n emit LastAccruingBlockChanged(oldLastAccruingBlock, _lastAccruingBlock);\n }\n\n function getBlockNumber() public view returns (uint256) {\n return block.number;\n }\n\n /*** Admin Functions ***/\n\n function _become(IVRTVaultProxy vrtVaultProxy) external {\n require(msg.sender == vrtVaultProxy.admin(), \"only proxy admin can change brains\");\n vrtVaultProxy._acceptImplementation();\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlAddress New address for the access control\n */\n function setAccessControl(address newAccessControlAddress) external onlyAdmin {\n _setAccessControlManager(newAccessControlAddress);\n }\n}\n" + }, + "contracts/VRTVault/VRTVaultProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VRTVaultStorage.sol\";\n\ncontract VRTVaultProxy is VRTVaultAdminStorage {\n /**\n * @notice Emitted when pendingImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingImplementation is accepted, which means VRT Vault implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor(address implementation_, address vrtAddress_, uint256 interestRatePerBlock_) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_);\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(\n implementation_,\n abi.encodeWithSignature(\"initialize(address,uint256)\", vrtAddress_, interestRatePerBlock_)\n );\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n */\n function _setImplementation(address implementation_) public {\n require(msg.sender == admin, \"VRTVaultProxy::_setImplementation: admin only\");\n require(implementation_ != address(0), \"VRTVaultProxy::_setImplementation: invalid implementation address\");\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public {\n require(msg.sender == admin, \"Only admin can set Pending Implementation\");\n\n address oldPendingImplementation = pendingImplementation;\n\n pendingImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Accepts new implementation of VRT Vault. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n */\n function _acceptImplementation() public {\n // Check caller is pendingImplementation\n require(\n msg.sender == pendingImplementation,\n \"only address marked as pendingImplementation can accept Implementation\"\n );\n\n // Save current values for inclusion in log\n address oldImplementation = implementation;\n address oldPendingImplementation = pendingImplementation;\n\n implementation = pendingImplementation;\n\n pendingImplementation = address(0);\n\n emit NewImplementation(oldImplementation, implementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n */\n function _setPendingAdmin(address newPendingAdmin) public {\n // Check caller = admin\n require(msg.sender == admin, \"only admin can set pending admin\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @dev return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public {\n // Check caller is pendingAdmin\n require(msg.sender == pendingAdmin, \"only address marked as pendingAdmin can accept as Admin\");\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/VRTVault/VRTVaultStorage.sol": { + "content": "pragma solidity ^0.5.16;\nimport \"../Utils/SafeMath.sol\";\nimport \"../Utils/IBEP20.sol\";\n\ncontract VRTVaultAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of VRT Vault\n */\n address public implementation;\n\n /**\n * @notice Pending brains of VAI Vault\n */\n address public pendingImplementation;\n}\n\ncontract VRTVaultStorage is VRTVaultAdminStorage {\n /// @notice Guard variable for re-entrancy checks\n bool public _notEntered;\n\n /// @notice pause indicator for Vault\n bool public vaultPaused;\n\n /// @notice The VRT TOKEN!\n IBEP20 public vrt;\n\n /// @notice interestRate for accrual - per Block\n uint256 public interestRatePerBlock;\n\n /// @notice Info of each user.\n struct UserInfo {\n address userAddress;\n uint256 accrualStartBlockNumber;\n uint256 totalPrincipalAmount;\n uint256 lastWithdrawnBlockNumber;\n }\n\n // Info of each user that stakes tokens.\n mapping(address => UserInfo) public userInfo;\n\n /// @notice block number after which no interest will be accrued\n uint256 public lastAccruingBlock;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/XVSVault/XVSStore.sol": { + "content": "pragma solidity 0.5.16;\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/IBEP20.sol\";\n\n/**\n * @title XVS Store\n * @author Venus\n * @notice XVS Store responsible for distributing XVS rewards\n */\ncontract XVSStore {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice The Admin Address\n address public admin;\n\n /// @notice The pending admin address\n address public pendingAdmin;\n\n /// @notice The Owner Address\n address public owner;\n\n /// @notice The reward tokens\n mapping(address => bool) public rewardTokens;\n\n /// @notice Emitted when pendingAdmin is changed\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /// @notice Event emitted when admin changed\n event AdminTransferred(address indexed oldAdmin, address indexed newAdmin);\n\n /// @notice Event emitted when owner changed\n event OwnerTransferred(address indexed oldOwner, address indexed newOwner);\n\n constructor() public {\n admin = msg.sender;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"only owner can\");\n _;\n }\n\n /**\n * @notice Safely transfer rewards. Only active reward tokens can be sent using this function.\n * Only callable by owner\n * @dev Safe reward token transfer function, just in case if rounding error causes pool to not have enough tokens.\n * @param token Reward token to transfer\n * @param _to Destination address of the reward\n * @param _amount Amount to transfer\n */\n function safeRewardTransfer(address token, address _to, uint256 _amount) external onlyOwner {\n require(rewardTokens[token] == true, \"only reward token can\");\n\n if (address(token) != address(0)) {\n uint256 tokenBalance = IBEP20(token).balanceOf(address(this));\n if (_amount > tokenBalance) {\n IBEP20(token).safeTransfer(_to, tokenBalance);\n } else {\n IBEP20(token).safeTransfer(_to, _amount);\n }\n }\n }\n\n /**\n * @notice Allows the admin to propose a new admin\n * Only callable admin\n * @param _admin Propose an account as admin of the XVS store\n */\n function setPendingAdmin(address _admin) external onlyAdmin {\n address oldPendingAdmin = pendingAdmin;\n pendingAdmin = _admin;\n emit NewPendingAdmin(oldPendingAdmin, _admin);\n }\n\n /**\n * @notice Allows an account that is pending as admin to accept the role\n * nly calllable by the pending admin\n */\n function acceptAdmin() external {\n require(msg.sender == pendingAdmin, \"only pending admin\");\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n admin = pendingAdmin;\n pendingAdmin = address(0);\n\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n emit AdminTransferred(oldAdmin, admin);\n }\n\n /**\n * @notice Set the contract owner\n * @param _owner The address of the owner to set\n * Only callable admin\n */\n function setNewOwner(address _owner) external onlyAdmin {\n require(_owner != address(0), \"new owner is the zero address\");\n address oldOwner = owner;\n owner = _owner;\n emit OwnerTransferred(oldOwner, _owner);\n }\n\n /**\n * @notice Set or disable a reward token\n * @param _tokenAddress The address of a token to set as active or inactive\n * @param status Set whether a reward token is active or not\n */\n function setRewardToken(address _tokenAddress, bool status) external {\n require(msg.sender == admin || msg.sender == owner, \"only admin or owner can\");\n rewardTokens[_tokenAddress] = status;\n }\n\n /**\n * @notice Security function to allow the owner of the contract to withdraw from the contract\n * @param _tokenAddress Reward token address to withdraw\n * @param _amount Amount of token to withdraw\n */\n function emergencyRewardWithdraw(address _tokenAddress, uint256 _amount) external onlyOwner {\n IBEP20(_tokenAddress).safeTransfer(address(msg.sender), _amount);\n }\n}\n" + }, + "contracts/XVSVault/XVSVault.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Utils/ECDSA.sol\";\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/IBEP20.sol\";\nimport \"./XVSVaultStorage.sol\";\nimport \"../Tokens/Prime/IPrime.sol\";\nimport \"../Utils/SafeCast.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV5.sol\";\nimport \"@venusprotocol/solidity-utilities/contracts/TimeManagerV5.sol\";\n\nimport { XVSStore } from \"./XVSStore.sol\";\nimport { XVSVaultProxy } from \"./XVSVaultProxy.sol\";\n\n/**\n * @title XVS Vault\n * @author Venus\n * @notice The XVS Vault allows XVS holders to lock their XVS to recieve voting rights in Venus governance and are rewarded with XVS.\n */\ncontract XVSVault is XVSVaultStorage, ECDSA, AccessControlledV5, TimeManagerV5 {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice The upper bound for the lock period in a pool, 10 years\n uint256 public constant MAX_LOCK_PERIOD = 60 * 60 * 24 * 365 * 10;\n\n /// @notice Event emitted when deposit\n event Deposit(address indexed user, address indexed rewardToken, uint256 indexed pid, uint256 amount);\n\n /// @notice Event emitted when execute withrawal\n event ExecutedWithdrawal(address indexed user, address indexed rewardToken, uint256 indexed pid, uint256 amount);\n\n /// @notice Event emitted when request withrawal\n event RequestedWithdrawal(address indexed user, address indexed rewardToken, uint256 indexed pid, uint256 amount);\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChangedV2(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /// @notice An event thats emitted when a delegate account's vote balance changes\n event DelegateVotesChangedV2(address indexed delegate, uint previousBalance, uint newBalance);\n\n /// @notice An event emitted when the reward store address is updated\n event StoreUpdated(address oldXvs, address oldStore, address newXvs, address newStore);\n\n /// @notice An event emitted when the withdrawal locking period is updated for a pool\n event WithdrawalLockingPeriodUpdated(address indexed rewardToken, uint indexed pid, uint oldPeriod, uint newPeriod);\n\n /// @notice An event emitted when the reward amount per block or second is modified for a pool\n event RewardAmountUpdated(address indexed rewardToken, uint oldReward, uint newReward);\n\n /// @notice An event emitted when a new pool is added\n event PoolAdded(\n address indexed rewardToken,\n uint indexed pid,\n address indexed token,\n uint allocPoints,\n uint rewardPerBlockOrSecond,\n uint lockPeriod\n );\n\n /// @notice An event emitted when a pool allocation points are updated\n event PoolUpdated(address indexed rewardToken, uint indexed pid, uint oldAllocPoints, uint newAllocPoints);\n\n /// @notice Event emitted when reward claimed\n event Claim(address indexed user, address indexed rewardToken, uint256 indexed pid, uint256 amount);\n\n /// @notice Event emitted when vault is paused\n event VaultPaused(address indexed admin);\n\n /// @notice Event emitted when vault is resumed after pause\n event VaultResumed(address indexed admin);\n\n /// @notice Event emitted when protocol logs a debt to a user due to insufficient funds for pending reward distribution\n event VaultDebtUpdated(\n address indexed rewardToken,\n address indexed userAddress,\n uint256 oldOwedAmount,\n uint256 newOwedAmount\n );\n\n /// @notice Emitted when prime token contract address is changed\n event NewPrimeToken(\n IPrime indexed oldPrimeToken,\n IPrime indexed newPrimeToken,\n address oldPrimeRewardToken,\n address newPrimeRewardToken,\n uint256 oldPrimePoolId,\n uint256 newPrimePoolId\n );\n\n /**\n * @notice XVSVault constructor\n */\n constructor() public {\n admin = msg.sender;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n /**\n * @dev Prevents functions to execute when vault is paused.\n */\n modifier isActive() {\n require(!vaultPaused, \"Vault is paused\");\n _;\n }\n\n /**\n * @notice Pauses vault\n */\n function pause() external {\n _checkAccessAllowed(\"pause()\");\n require(!vaultPaused, \"Vault is already paused\");\n vaultPaused = true;\n emit VaultPaused(msg.sender);\n }\n\n /**\n * @notice Resume vault\n */\n function resume() external {\n _checkAccessAllowed(\"resume()\");\n require(vaultPaused, \"Vault is not paused\");\n vaultPaused = false;\n emit VaultResumed(msg.sender);\n }\n\n /**\n * @notice Returns the number of pools with the specified reward token\n * @param rewardToken Reward token address\n * @return Number of pools that distribute the specified token as a reward\n */\n function poolLength(address rewardToken) external view returns (uint256) {\n return poolInfos[rewardToken].length;\n }\n\n /**\n * @notice Returns the number of reward tokens created per block or second\n * @param _rewardToken Reward token address\n * @return Number of reward tokens created per block or second\n */\n function rewardTokenAmountsPerBlock(address _rewardToken) external view returns (uint256) {\n return rewardTokenAmountsPerBlockOrSecond[_rewardToken];\n }\n\n /**\n * @notice Add a new token pool\n * @dev This vault DOES NOT support deflationary tokens — it expects that\n * the amount of transferred tokens would equal the actually deposited\n * amount. In practice this means that this vault DOES NOT support USDT\n * and similar tokens (that do not provide these guarantees).\n * @param _rewardToken Reward token address\n * @param _allocPoint Number of allocation points assigned to this pool\n * @param _token Staked token\n * @param _rewardPerBlockOrSecond Initial reward per block or second, in terms of _rewardToken\n * @param _lockPeriod A period between withdrawal request and a moment when it's executable\n */\n function add(\n address _rewardToken,\n uint256 _allocPoint,\n IBEP20 _token,\n uint256 _rewardPerBlockOrSecond,\n uint256 _lockPeriod\n ) external {\n _checkAccessAllowed(\"add(address,uint256,address,uint256,uint256)\");\n _ensureNonzeroAddress(_rewardToken);\n _ensureNonzeroAddress(address(_token));\n require(address(xvsStore) != address(0), \"Store contract address is empty\");\n require(_allocPoint > 0, \"Alloc points must not be zero\");\n\n massUpdatePools(_rewardToken);\n\n PoolInfo[] storage poolInfo = poolInfos[_rewardToken];\n\n uint256 length = poolInfo.length;\n for (uint256 pid = 0; pid < length; ++pid) {\n require(poolInfo[pid].token != _token, \"Pool already added\");\n }\n\n // We use balanceOf to get the supply amount, so shouldn't be possible to\n // configure pools with different reward token but the same staked token\n require(!isStakedToken[address(_token)], \"Token exists in other pool\");\n\n totalAllocPoints[_rewardToken] = totalAllocPoints[_rewardToken].add(_allocPoint);\n\n rewardTokenAmountsPerBlockOrSecond[_rewardToken] = _rewardPerBlockOrSecond;\n\n poolInfo.push(\n PoolInfo({\n token: _token,\n allocPoint: _allocPoint,\n lastRewardBlockOrSecond: getBlockNumberOrTimestamp(),\n accRewardPerShare: 0,\n lockPeriod: _lockPeriod\n })\n );\n isStakedToken[address(_token)] = true;\n\n XVSStore(xvsStore).setRewardToken(_rewardToken, true);\n\n emit PoolAdded(\n _rewardToken,\n poolInfo.length - 1,\n address(_token),\n _allocPoint,\n _rewardPerBlockOrSecond,\n _lockPeriod\n );\n }\n\n /**\n * @notice Update the given pool's reward allocation point\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n * @param _allocPoint Number of allocation points assigned to this pool\n */\n function set(address _rewardToken, uint256 _pid, uint256 _allocPoint) external {\n _checkAccessAllowed(\"set(address,uint256,uint256)\");\n _ensureValidPool(_rewardToken, _pid);\n\n massUpdatePools(_rewardToken);\n\n PoolInfo[] storage poolInfo = poolInfos[_rewardToken];\n uint256 newTotalAllocPoints = totalAllocPoints[_rewardToken].sub(poolInfo[_pid].allocPoint).add(_allocPoint);\n require(newTotalAllocPoints > 0, \"Alloc points per reward token must not be zero\");\n\n uint256 oldAllocPoints = poolInfo[_pid].allocPoint;\n poolInfo[_pid].allocPoint = _allocPoint;\n totalAllocPoints[_rewardToken] = newTotalAllocPoints;\n\n emit PoolUpdated(_rewardToken, _pid, oldAllocPoints, _allocPoint);\n }\n\n /**\n * @notice Update the given reward token's amount per block or second\n * @param _rewardToken Reward token address\n * @param _rewardAmount Number of allocation points assigned to this pool\n */\n function setRewardAmountPerBlockOrSecond(address _rewardToken, uint256 _rewardAmount) external {\n _checkAccessAllowed(\"setRewardAmountPerBlockOrSecond(address,uint256)\");\n require(XVSStore(xvsStore).rewardTokens(_rewardToken), \"Invalid reward token\");\n massUpdatePools(_rewardToken);\n uint256 oldReward = rewardTokenAmountsPerBlockOrSecond[_rewardToken];\n rewardTokenAmountsPerBlockOrSecond[_rewardToken] = _rewardAmount;\n\n emit RewardAmountUpdated(_rewardToken, oldReward, _rewardAmount);\n }\n\n /**\n * @notice Update the lock period after which a requested withdrawal can be executed\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n * @param _newPeriod New lock period\n */\n function setWithdrawalLockingPeriod(address _rewardToken, uint256 _pid, uint256 _newPeriod) external {\n _checkAccessAllowed(\"setWithdrawalLockingPeriod(address,uint256,uint256)\");\n _ensureValidPool(_rewardToken, _pid);\n require(_newPeriod > 0 && _newPeriod < MAX_LOCK_PERIOD, \"Invalid new locking period\");\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n uint256 oldPeriod = pool.lockPeriod;\n pool.lockPeriod = _newPeriod;\n\n emit WithdrawalLockingPeriodUpdated(_rewardToken, _pid, oldPeriod, _newPeriod);\n }\n\n /**\n * @notice Deposit XVSVault for XVS allocation\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _amount The amount to deposit to vault\n */\n function deposit(address _rewardToken, uint256 _pid, uint256 _amount) external nonReentrant isActive {\n _ensureValidPool(_rewardToken, _pid);\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n UserInfo storage user = userInfos[_rewardToken][_pid][msg.sender];\n _updatePool(_rewardToken, _pid);\n require(pendingWithdrawalsBeforeUpgrade(_rewardToken, _pid, msg.sender) == 0, \"execute pending withdrawal\");\n\n if (user.amount > 0) {\n uint256 pending = _computeReward(user, pool);\n if (pending > 0) {\n _transferReward(_rewardToken, msg.sender, pending);\n emit Claim(msg.sender, _rewardToken, _pid, pending);\n }\n }\n pool.token.safeTransferFrom(msg.sender, address(this), _amount);\n user.amount = user.amount.add(_amount);\n user.rewardDebt = _cumulativeReward(user, pool);\n\n // Update Delegate Amount\n if (address(pool.token) == xvsAddress) {\n _moveDelegates(address(0), delegates[msg.sender], safe96(_amount, \"XVSVault::deposit: votes overflow\"));\n }\n\n if (primeRewardToken == _rewardToken && _pid == primePoolId) {\n primeToken.xvsUpdated(msg.sender);\n }\n\n emit Deposit(msg.sender, _rewardToken, _pid, _amount);\n }\n\n /**\n * @notice Claim rewards for pool\n * @param _account The account for which to claim rewards\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n */\n function claim(address _account, address _rewardToken, uint256 _pid) external nonReentrant isActive {\n _ensureValidPool(_rewardToken, _pid);\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n UserInfo storage user = userInfos[_rewardToken][_pid][_account];\n _updatePool(_rewardToken, _pid);\n require(pendingWithdrawalsBeforeUpgrade(_rewardToken, _pid, _account) == 0, \"execute pending withdrawal\");\n\n if (user.amount > 0) {\n uint256 pending = _computeReward(user, pool);\n\n if (pending > 0) {\n user.rewardDebt = _cumulativeReward(user, pool);\n\n _transferReward(_rewardToken, _account, pending);\n emit Claim(_account, _rewardToken, _pid, pending);\n }\n }\n }\n\n /**\n * @notice Pushes withdrawal request to the requests array and updates\n * the pending withdrawals amount. The requests are always sorted\n * by unlock time (descending) so that the earliest to execute requests\n * are always at the end of the array.\n * @param _user The user struct storage pointer\n * @param _requests The user's requests array storage pointer\n * @param _amount The amount being requested\n */\n function pushWithdrawalRequest(\n UserInfo storage _user,\n WithdrawalRequest[] storage _requests,\n uint _amount,\n uint _lockedUntil\n ) internal {\n uint i = _requests.length;\n _requests.push(WithdrawalRequest(0, 0, 1));\n // Keep it sorted so that the first to get unlocked request is always at the end\n for (; i > 0 && _requests[i - 1].lockedUntil <= _lockedUntil; --i) {\n _requests[i] = _requests[i - 1];\n }\n _requests[i] = WithdrawalRequest(_amount, _lockedUntil.toUint128(), 1);\n _user.pendingWithdrawals = _user.pendingWithdrawals.add(_amount);\n }\n\n /**\n * @notice Pops the requests with unlock time < now from the requests\n * array and deducts the computed amount from the user's pending\n * withdrawals counter. Assumes that the requests array is sorted\n * by unclock time (descending).\n * @dev This function **removes** the eligible requests from the requests\n * array. If this function is called, the withdrawal should actually\n * happen (or the transaction should be reverted).\n * @param _user The user struct storage pointer\n * @param _requests The user's requests array storage pointer\n * @return beforeUpgradeWithdrawalAmount The amount eligible for withdrawal before upgrade (this amount should be\n * sent to the user, otherwise the state would be inconsistent).\n * @return afterUpgradeWithdrawalAmount The amount eligible for withdrawal after upgrade (this amount should be\n * sent to the user, otherwise the state would be inconsistent).\n */\n function popEligibleWithdrawalRequests(\n UserInfo storage _user,\n WithdrawalRequest[] storage _requests\n ) internal returns (uint beforeUpgradeWithdrawalAmount, uint afterUpgradeWithdrawalAmount) {\n // Since the requests are sorted by their unlock time, we can just\n // pop them from the array and stop at the first not-yet-eligible one\n for (uint i = _requests.length; i > 0 && isUnlocked(_requests[i - 1]); --i) {\n if (_requests[i - 1].afterUpgrade == 1) {\n afterUpgradeWithdrawalAmount = afterUpgradeWithdrawalAmount.add(_requests[i - 1].amount);\n } else {\n beforeUpgradeWithdrawalAmount = beforeUpgradeWithdrawalAmount.add(_requests[i - 1].amount);\n }\n\n _requests.pop();\n }\n _user.pendingWithdrawals = _user.pendingWithdrawals.sub(\n afterUpgradeWithdrawalAmount.add(beforeUpgradeWithdrawalAmount)\n );\n return (beforeUpgradeWithdrawalAmount, afterUpgradeWithdrawalAmount);\n }\n\n /**\n * @notice Checks if the request is eligible for withdrawal.\n * @param _request The request struct storage pointer\n * @return True if the request is eligible for withdrawal, false otherwise\n */\n function isUnlocked(WithdrawalRequest storage _request) private view returns (bool) {\n return _request.lockedUntil <= block.timestamp;\n }\n\n /**\n * @notice Execute withdrawal to XVSVault for XVS allocation\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n */\n function executeWithdrawal(address _rewardToken, uint256 _pid) external nonReentrant isActive {\n _ensureValidPool(_rewardToken, _pid);\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n UserInfo storage user = userInfos[_rewardToken][_pid][msg.sender];\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][msg.sender];\n\n uint256 beforeUpgradeWithdrawalAmount;\n uint256 afterUpgradeWithdrawalAmount;\n\n (beforeUpgradeWithdrawalAmount, afterUpgradeWithdrawalAmount) = popEligibleWithdrawalRequests(user, requests);\n require(beforeUpgradeWithdrawalAmount > 0 || afterUpgradeWithdrawalAmount > 0, \"nothing to withdraw\");\n\n // Having both old-style and new-style requests is not allowed and shouldn't be possible\n require(beforeUpgradeWithdrawalAmount == 0 || afterUpgradeWithdrawalAmount == 0, \"inconsistent state\");\n\n if (beforeUpgradeWithdrawalAmount > 0) {\n _updatePool(_rewardToken, _pid);\n uint256 pending = user.amount.mul(pool.accRewardPerShare).div(1e12).sub(user.rewardDebt);\n XVSStore(xvsStore).safeRewardTransfer(_rewardToken, msg.sender, pending);\n user.amount = user.amount.sub(beforeUpgradeWithdrawalAmount);\n user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(1e12);\n pool.token.safeTransfer(address(msg.sender), beforeUpgradeWithdrawalAmount);\n } else {\n user.amount = user.amount.sub(afterUpgradeWithdrawalAmount);\n totalPendingWithdrawals[_rewardToken][_pid] = totalPendingWithdrawals[_rewardToken][_pid].sub(\n afterUpgradeWithdrawalAmount\n );\n pool.token.safeTransfer(address(msg.sender), afterUpgradeWithdrawalAmount);\n }\n\n emit ExecutedWithdrawal(\n msg.sender,\n _rewardToken,\n _pid,\n beforeUpgradeWithdrawalAmount.add(afterUpgradeWithdrawalAmount)\n );\n }\n\n /**\n * @notice Returns before and after upgrade pending withdrawal amount\n * @param _requests The user's requests array storage pointer\n * @return beforeUpgradeWithdrawalAmount The amount eligible for withdrawal before upgrade\n * @return afterUpgradeWithdrawalAmount The amount eligible for withdrawal after upgrade\n */\n function getRequestedWithdrawalAmount(\n WithdrawalRequest[] storage _requests\n ) internal view returns (uint beforeUpgradeWithdrawalAmount, uint afterUpgradeWithdrawalAmount) {\n for (uint i = _requests.length; i > 0; --i) {\n if (_requests[i - 1].afterUpgrade == 1) {\n afterUpgradeWithdrawalAmount = afterUpgradeWithdrawalAmount.add(_requests[i - 1].amount);\n } else {\n beforeUpgradeWithdrawalAmount = beforeUpgradeWithdrawalAmount.add(_requests[i - 1].amount);\n }\n }\n return (beforeUpgradeWithdrawalAmount, afterUpgradeWithdrawalAmount);\n }\n\n /**\n * @notice Request withdrawal to XVSVault for XVS allocation\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _amount The amount to withdraw from the vault\n */\n function requestWithdrawal(address _rewardToken, uint256 _pid, uint256 _amount) external nonReentrant isActive {\n _ensureValidPool(_rewardToken, _pid);\n require(_amount > 0, \"requested amount cannot be zero\");\n UserInfo storage user = userInfos[_rewardToken][_pid][msg.sender];\n require(user.amount >= user.pendingWithdrawals.add(_amount), \"requested amount is invalid\");\n\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][msg.sender];\n\n uint beforeUpgradeWithdrawalAmount;\n\n (beforeUpgradeWithdrawalAmount, ) = getRequestedWithdrawalAmount(requests);\n require(beforeUpgradeWithdrawalAmount == 0, \"execute pending withdrawal\");\n\n _updatePool(_rewardToken, _pid);\n uint256 pending = _computeReward(user, pool);\n _transferReward(_rewardToken, msg.sender, pending);\n\n uint lockedUntil = pool.lockPeriod.add(block.timestamp);\n\n pushWithdrawalRequest(user, requests, _amount, lockedUntil);\n totalPendingWithdrawals[_rewardToken][_pid] = totalPendingWithdrawals[_rewardToken][_pid].add(_amount);\n user.rewardDebt = _cumulativeReward(user, pool);\n\n // Update Delegate Amount\n if (address(pool.token) == xvsAddress) {\n _moveDelegates(\n delegates[msg.sender],\n address(0),\n safe96(_amount, \"XVSVault::requestWithdrawal: votes overflow\")\n );\n }\n\n if (primeRewardToken == _rewardToken && _pid == primePoolId) {\n primeToken.xvsUpdated(msg.sender);\n }\n\n emit Claim(msg.sender, _rewardToken, _pid, pending);\n emit RequestedWithdrawal(msg.sender, _rewardToken, _pid, _amount);\n }\n\n /**\n * @notice Get unlocked withdrawal amount\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _user The User Address\n * @return withdrawalAmount Amount that the user can withdraw\n */\n function getEligibleWithdrawalAmount(\n address _rewardToken,\n uint256 _pid,\n address _user\n ) external view returns (uint withdrawalAmount) {\n _ensureValidPool(_rewardToken, _pid);\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][_user];\n // Since the requests are sorted by their unlock time, we can take\n // the entries from the end of the array and stop at the first\n // not-yet-eligible one\n for (uint i = requests.length; i > 0 && isUnlocked(requests[i - 1]); --i) {\n withdrawalAmount = withdrawalAmount.add(requests[i - 1].amount);\n }\n return withdrawalAmount;\n }\n\n /**\n * @notice Get requested amount\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _user The User Address\n * @return Total amount of requested but not yet executed withdrawals (including both executable and locked ones)\n */\n function getRequestedAmount(address _rewardToken, uint256 _pid, address _user) external view returns (uint256) {\n _ensureValidPool(_rewardToken, _pid);\n UserInfo storage user = userInfos[_rewardToken][_pid][_user];\n return user.pendingWithdrawals;\n }\n\n /**\n * @notice Returns the array of withdrawal requests that have not been executed yet\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _user The User Address\n * @return An array of withdrawal requests\n */\n function getWithdrawalRequests(\n address _rewardToken,\n uint256 _pid,\n address _user\n ) external view returns (WithdrawalRequest[] memory) {\n _ensureValidPool(_rewardToken, _pid);\n return withdrawalRequests[_rewardToken][_pid][_user];\n }\n\n /**\n * @notice View function to see pending XVSs on frontend\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n * @param _user User address\n * @return Reward the user is eligible for in this pool, in terms of _rewardToken\n */\n function pendingReward(address _rewardToken, uint256 _pid, address _user) external view returns (uint256) {\n _ensureValidPool(_rewardToken, _pid);\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n UserInfo storage user = userInfos[_rewardToken][_pid][_user];\n uint256 accRewardPerShare = pool.accRewardPerShare;\n uint256 supply = pool.token.balanceOf(address(this)).sub(totalPendingWithdrawals[_rewardToken][_pid]);\n uint256 curBlockNumberOrSecond = getBlockNumberOrTimestamp();\n uint256 rewardTokenPerBlockOrSecond = rewardTokenAmountsPerBlockOrSecond[_rewardToken];\n if (curBlockNumberOrSecond > pool.lastRewardBlockOrSecond && supply != 0) {\n uint256 multiplier = curBlockNumberOrSecond.sub(pool.lastRewardBlockOrSecond);\n uint256 reward = multiplier.mul(rewardTokenPerBlockOrSecond).mul(pool.allocPoint).div(\n totalAllocPoints[_rewardToken]\n );\n accRewardPerShare = accRewardPerShare.add(reward.mul(1e12).div(supply));\n }\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][_user];\n (, uint256 afterUpgradeWithdrawalAmount) = getRequestedWithdrawalAmount(requests);\n return user.amount.sub(afterUpgradeWithdrawalAmount).mul(accRewardPerShare).div(1e12).sub(user.rewardDebt);\n }\n\n // Update reward variables for all pools. Be careful of gas spending!\n function massUpdatePools(address _rewardToken) internal {\n uint256 length = poolInfos[_rewardToken].length;\n for (uint256 pid = 0; pid < length; ++pid) {\n _updatePool(_rewardToken, pid);\n }\n }\n\n /**\n * @notice Update reward variables of the given pool to be up-to-date\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n */\n function updatePool(address _rewardToken, uint256 _pid) external isActive {\n _ensureValidPool(_rewardToken, _pid);\n _updatePool(_rewardToken, _pid);\n }\n\n // Update reward variables of the given pool to be up-to-date.\n function _updatePool(address _rewardToken, uint256 _pid) internal {\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n if (getBlockNumberOrTimestamp() <= pool.lastRewardBlockOrSecond) {\n return;\n }\n uint256 supply = pool.token.balanceOf(address(this));\n supply = supply.sub(totalPendingWithdrawals[_rewardToken][_pid]);\n if (supply == 0) {\n pool.lastRewardBlockOrSecond = getBlockNumberOrTimestamp();\n return;\n }\n uint256 curBlockNumberOrSecond = getBlockNumberOrTimestamp();\n uint256 multiplier = curBlockNumberOrSecond.sub(pool.lastRewardBlockOrSecond);\n uint256 reward = multiplier.mul(rewardTokenAmountsPerBlockOrSecond[_rewardToken]).mul(pool.allocPoint).div(\n totalAllocPoints[_rewardToken]\n );\n pool.accRewardPerShare = pool.accRewardPerShare.add(reward.mul(1e12).div(supply));\n pool.lastRewardBlockOrSecond = getBlockNumberOrTimestamp();\n }\n\n function _ensureValidPool(address rewardToken, uint256 pid) internal view {\n require(pid < poolInfos[rewardToken].length, \"vault: pool exists?\");\n }\n\n /**\n * @notice Get user info with reward token address and pid\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n * @param _user User address\n * @return amount Deposited amount\n * @return rewardDebt Reward debt (technical value used to track past payouts)\n * @return pendingWithdrawals Requested but not yet executed withdrawals\n */\n function getUserInfo(\n address _rewardToken,\n uint256 _pid,\n address _user\n ) external view returns (uint256 amount, uint256 rewardDebt, uint256 pendingWithdrawals) {\n _ensureValidPool(_rewardToken, _pid);\n UserInfo storage user = userInfos[_rewardToken][_pid][_user];\n amount = user.amount;\n rewardDebt = user.rewardDebt;\n pendingWithdrawals = user.pendingWithdrawals;\n }\n\n /**\n * @notice Gets the total pending withdrawal amount of a user before upgrade\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _user The address of the user\n * @return beforeUpgradeWithdrawalAmount Total pending withdrawal amount in requests made before the vault upgrade\n */\n function pendingWithdrawalsBeforeUpgrade(\n address _rewardToken,\n uint256 _pid,\n address _user\n ) public view returns (uint256 beforeUpgradeWithdrawalAmount) {\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][_user];\n (beforeUpgradeWithdrawalAmount, ) = getRequestedWithdrawalAmount(requests);\n return beforeUpgradeWithdrawalAmount;\n }\n\n /**\n * @notice Get the XVS stake balance of an account (excluding the pending withdrawals)\n * @param account The address of the account to check\n * @return The balance that user staked\n */\n function getStakeAmount(address account) internal view returns (uint96) {\n require(xvsAddress != address(0), \"XVSVault::getStakeAmount: xvs address is not set\");\n\n PoolInfo[] storage poolInfo = poolInfos[xvsAddress];\n\n uint256 length = poolInfo.length;\n for (uint256 pid = 0; pid < length; ++pid) {\n if (address(poolInfo[pid].token) == address(xvsAddress)) {\n UserInfo storage user = userInfos[xvsAddress][pid][account];\n return safe96(user.amount.sub(user.pendingWithdrawals), \"XVSVault::getStakeAmount: votes overflow\");\n }\n }\n return uint96(0);\n }\n\n /**\n * @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The address to delegate votes to\n */\n function delegate(address delegatee) external isActive {\n return _delegate(msg.sender, delegatee);\n }\n\n /**\n * @notice Delegates votes from signatory to `delegatee`\n * @param delegatee The address to delegate votes to\n * @param nonce The contract state required to match the signature\n * @param expiry The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n function delegateBySig(\n address delegatee,\n uint nonce,\n uint expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external isActive {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(\"XVSVault\")), getChainId(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ECDSA.recover(digest, v, r, s);\n require(nonce == nonces[signatory]++, \"XVSVault::delegateBySig: invalid nonce\");\n require(block.timestamp <= expiry, \"XVSVault::delegateBySig: signature expired\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Gets the current votes balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for `account`\n */\n function getCurrentVotes(address account) external view returns (uint96) {\n uint32 nCheckpoints = numCheckpoints[account];\n return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n function _delegate(address delegator, address delegatee) internal {\n address currentDelegate = delegates[delegator];\n uint96 delegatorBalance = getStakeAmount(delegator);\n delegates[delegator] = delegatee;\n\n emit DelegateChangedV2(delegator, currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {\n if (srcRep != dstRep && amount > 0) {\n if (srcRep != address(0)) {\n uint32 srcRepNum = numCheckpoints[srcRep];\n uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n uint96 srcRepNew = sub96(srcRepOld, amount, \"XVSVault::_moveVotes: vote amount underflows\");\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint96 dstRepNew = add96(dstRepOld, amount, \"XVSVault::_moveVotes: vote amount overflows\");\n _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {\n uint32 blockNumberOrSecond = safe32(\n getBlockNumberOrTimestamp(),\n \"XVSVault::_writeCheckpoint: block number or second exceeds 32 bits\"\n );\n\n if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlockOrSecond == blockNumberOrSecond) {\n checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n } else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumberOrSecond, newVotes);\n numCheckpoints[delegatee] = nCheckpoints + 1;\n }\n\n emit DelegateVotesChangedV2(delegatee, oldVotes, newVotes);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n < 2 ** 32, errorMessage);\n return uint32(n);\n }\n\n function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {\n require(n < 2 ** 96, errorMessage);\n return uint96(n);\n }\n\n function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n uint96 c = a + b;\n require(c >= a, errorMessage);\n return c;\n }\n\n function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n function getChainId() internal pure returns (uint) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n return chainId;\n }\n\n /**\n * @notice Determine the xvs stake balance for an account\n * @param account The address of the account to check\n * @param blockNumberOrSecond The block number or second to get the vote balance at\n * @return The balance that user staked\n */\n function getPriorVotes(address account, uint256 blockNumberOrSecond) external view returns (uint96) {\n require(blockNumberOrSecond < getBlockNumberOrTimestamp(), \"XVSVault::getPriorVotes: not yet determined\");\n\n uint32 nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n }\n\n // First check most recent balance\n if (checkpoints[account][nCheckpoints - 1].fromBlockOrSecond <= blockNumberOrSecond) {\n return checkpoints[account][nCheckpoints - 1].votes;\n }\n\n // Next check implicit zero balance\n if (checkpoints[account][0].fromBlockOrSecond > blockNumberOrSecond) {\n return 0;\n }\n\n uint32 lower = 0;\n uint32 upper = nCheckpoints - 1;\n while (upper > lower) {\n uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n Checkpoint memory cp = checkpoints[account][center];\n if (cp.fromBlockOrSecond == blockNumberOrSecond) {\n return cp.votes;\n } else if (cp.fromBlockOrSecond < blockNumberOrSecond) {\n lower = center;\n } else {\n upper = center - 1;\n }\n }\n return checkpoints[account][lower].votes;\n }\n\n /*** Admin Functions ***/\n\n function _become(XVSVaultProxy xvsVaultProxy) external {\n require(msg.sender == xvsVaultProxy.admin(), \"only proxy admin can change brains\");\n require(xvsVaultProxy._acceptImplementation() == 0, \"change not authorized\");\n }\n\n function setXvsStore(address _xvs, address _xvsStore) external onlyAdmin {\n _ensureNonzeroAddress(_xvs);\n _ensureNonzeroAddress(_xvsStore);\n\n address oldXvsContract = xvsAddress;\n address oldStore = xvsStore;\n require(oldXvsContract == address(0), \"already initialized\");\n\n xvsAddress = _xvs;\n xvsStore = _xvsStore;\n\n _notEntered = true;\n\n emit StoreUpdated(oldXvsContract, oldStore, _xvs, _xvsStore);\n }\n\n /**\n * @notice Sets the address of the prime token contract\n * @param _primeToken address of the prime token contract\n * @param _primeRewardToken address of reward token\n * @param _primePoolId pool id for reward\n */\n function setPrimeToken(IPrime _primeToken, address _primeRewardToken, uint256 _primePoolId) external onlyAdmin {\n require(address(_primeToken) != address(0), \"prime token cannot be zero address\");\n require(_primeRewardToken != address(0), \"reward cannot be zero address\");\n\n _ensureValidPool(_primeRewardToken, _primePoolId);\n\n emit NewPrimeToken(primeToken, _primeToken, primeRewardToken, _primeRewardToken, primePoolId, _primePoolId);\n\n primeToken = _primeToken;\n primeRewardToken = _primeRewardToken;\n primePoolId = _primePoolId;\n }\n\n /**\n * @dev Initializes the contract to use either blocks or seconds\n * @param timeBased_ A boolean indicating whether the contract is based on time or block\n * If timeBased is true than blocksPerYear_ param is ignored as blocksOrSecondsPerYear is set to SECONDS_PER_YEAR\n * @param blocksPerYear_ The number of blocks per year\n */\n function initializeTimeManager(bool timeBased_, uint256 blocksPerYear_) external onlyAdmin {\n _initializeTimeManager(timeBased_, blocksPerYear_);\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlAddress New address for the access control\n */\n function setAccessControl(address newAccessControlAddress) external onlyAdmin {\n _setAccessControlManager(newAccessControlAddress);\n }\n\n /**\n * @dev Reverts if the provided address is a zero address\n * @param address_ Address to check\n */\n function _ensureNonzeroAddress(address address_) internal pure {\n require(address_ != address(0), \"zero address not allowed\");\n }\n\n /**\n * @dev Transfers the reward to the user, taking into account the rewards store\n * balance and the previous debt. If there are not enough rewards in the store,\n * transfers the available funds and records the debt amount in pendingRewardTransfers.\n * @param rewardToken Reward token address\n * @param userAddress User address\n * @param amount Reward amount, in reward tokens\n */\n function _transferReward(address rewardToken, address userAddress, uint256 amount) internal {\n address xvsStore_ = xvsStore;\n uint256 storeBalance = IBEP20(rewardToken).balanceOf(xvsStore_);\n uint256 debtDueToFailedTransfers = pendingRewardTransfers[rewardToken][userAddress];\n uint256 fullAmount = amount.add(debtDueToFailedTransfers);\n\n if (fullAmount <= storeBalance) {\n if (debtDueToFailedTransfers != 0) {\n pendingRewardTransfers[rewardToken][userAddress] = 0;\n emit VaultDebtUpdated(rewardToken, userAddress, debtDueToFailedTransfers, 0);\n }\n XVSStore(xvsStore_).safeRewardTransfer(rewardToken, userAddress, fullAmount);\n return;\n }\n // Overflow isn't possible due to the check above\n uint256 newOwedAmount = fullAmount - storeBalance;\n pendingRewardTransfers[rewardToken][userAddress] = newOwedAmount;\n emit VaultDebtUpdated(rewardToken, userAddress, debtDueToFailedTransfers, newOwedAmount);\n XVSStore(xvsStore_).safeRewardTransfer(rewardToken, userAddress, storeBalance);\n }\n\n /**\n * @dev Computes cumulative reward for all user's shares\n * @param user UserInfo storage struct\n * @param pool PoolInfo storage struct\n */\n function _cumulativeReward(UserInfo storage user, PoolInfo storage pool) internal view returns (uint256) {\n return user.amount.sub(user.pendingWithdrawals).mul(pool.accRewardPerShare).div(1e12);\n }\n\n /**\n * @dev Computes the reward for all user's shares\n * @param user UserInfo storage struct\n * @param pool PoolInfo storage struct\n */\n function _computeReward(UserInfo storage user, PoolInfo storage pool) internal view returns (uint256) {\n return _cumulativeReward(user, pool).sub(user.rewardDebt);\n }\n}\n" + }, + "contracts/XVSVault/XVSVaultErrorReporter.sol": { + "content": "pragma solidity ^0.5.16;\n\ncontract XVSVaultErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED\n }\n\n enum FailureInfo {\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n" + }, + "contracts/XVSVault/XVSVaultProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./XVSVaultStorage.sol\";\nimport \"./XVSVaultErrorReporter.sol\";\n\n/**\n * @title XVS Vault Proxy\n * @author Venus\n * @notice XVS Vault Proxy contract\n */\ncontract XVSVaultProxy is XVSVaultAdminStorage, XVSVaultErrorReporter {\n /**\n * @notice Emitted when pendingXVSVaultImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingXVSVaultImplementation is accepted, which means XVS Vault implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor() public {\n // Set admin to caller\n admin = msg.sender;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public returns (uint) {\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK);\n }\n\n address oldPendingImplementation = pendingXVSVaultImplementation;\n\n pendingXVSVaultImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingXVSVaultImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts new implementation of XVS Vault. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public returns (uint) {\n // Check caller is pendingImplementation\n if (msg.sender != pendingXVSVaultImplementation) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldImplementation = implementation;\n address oldPendingImplementation = pendingXVSVaultImplementation;\n\n implementation = pendingXVSVaultImplementation;\n\n pendingXVSVaultImplementation = address(0);\n\n emit NewImplementation(oldImplementation, implementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingXVSVaultImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public returns (uint) {\n // Check caller = admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK);\n }\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public returns (uint) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/XVSVault/XVSVaultStorage.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\nimport \"../Utils/IBEP20.sol\";\nimport \"../Tokens/Prime/IPrime.sol\";\n\ncontract XVSVaultAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of XVS Vault\n */\n address public implementation;\n\n /**\n * @notice Pending brains of XVS Vault\n */\n address public pendingXVSVaultImplementation;\n}\n\ncontract XVSVaultStorageV1 is XVSVaultAdminStorage {\n /// @notice Guard variable for re-entrancy checks\n bool internal _notEntered;\n\n /// @notice The reward token store\n address public xvsStore;\n\n /// @notice The xvs token address\n address public xvsAddress;\n\n // Reward tokens created per block or second indentified by reward token address.\n mapping(address => uint256) public rewardTokenAmountsPerBlockOrSecond;\n\n /// @notice Info of each user.\n struct UserInfo {\n uint256 amount;\n uint256 rewardDebt;\n uint256 pendingWithdrawals;\n }\n\n // Info of each pool.\n struct PoolInfo {\n IBEP20 token; // Address of token contract to stake.\n uint256 allocPoint; // How many allocation points assigned to this pool.\n uint256 lastRewardBlockOrSecond; // Last block number or second that reward tokens distribution occurs.\n uint256 accRewardPerShare; // Accumulated per share, times 1e12. See below.\n uint256 lockPeriod; // Min time between withdrawal request and its execution.\n }\n\n // Infomation about a withdrawal request\n struct WithdrawalRequest {\n uint256 amount;\n uint128 lockedUntil;\n uint128 afterUpgrade;\n }\n\n // Info of each user that stakes tokens.\n mapping(address => mapping(uint256 => mapping(address => UserInfo))) internal userInfos;\n\n // Info of each pool.\n mapping(address => PoolInfo[]) public poolInfos;\n\n // Total allocation points. Must be the sum of all allocation points in all pools.\n mapping(address => uint256) public totalAllocPoints;\n\n // Info of requested but not yet executed withdrawals\n mapping(address => mapping(uint256 => mapping(address => WithdrawalRequest[]))) internal withdrawalRequests;\n\n /// @notice DEPRECATED A record of each accounts delegate (before the voting power fix)\n mapping(address => address) private __oldDelegatesSlot;\n\n /// @notice A checkpoint for marking number of votes from a given block or second\n struct Checkpoint {\n uint32 fromBlockOrSecond;\n uint96 votes;\n }\n\n /// @notice DEPRECATED A record of votes checkpoints for each account, by index (before the voting power fix)\n mapping(address => mapping(uint32 => Checkpoint)) private __oldCheckpointsSlot;\n\n /// @notice DEPRECATED The number of checkpoints for each account (before the voting power fix)\n mapping(address => uint32) private __oldNumCheckpointsSlot;\n\n /// @notice A record of states for signing / validating signatures\n mapping(address => uint) public nonces;\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation struct used by the contract\n bytes32 public constant DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n}\n\ncontract XVSVaultStorage is XVSVaultStorageV1 {\n /// @notice A record of each accounts delegate\n mapping(address => address) public delegates;\n\n /// @notice A record of votes checkpoints for each account, by index\n mapping(address => mapping(uint32 => Checkpoint)) public checkpoints;\n\n /// @notice The number of checkpoints for each account\n mapping(address => uint32) public numCheckpoints;\n\n /// @notice Tracks pending withdrawals for all users for a particular reward token and pool id\n mapping(address => mapping(uint256 => uint256)) public totalPendingWithdrawals;\n\n /// @notice pause indicator for Vault\n bool public vaultPaused;\n\n /// @notice if the token is added to any of the pools\n mapping(address => bool) public isStakedToken;\n\n /// @notice Amount we owe to users because of failed transfer attempts\n mapping(address => mapping(address => uint256)) public pendingRewardTransfers;\n\n /// @notice Prime token contract address\n IPrime public primeToken;\n\n /// @notice Reward token for which prime token is issued for staking\n address public primeRewardToken;\n\n /// @notice Pool ID for which prime token is issued for staking\n uint256 public primePoolId;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/bscmainnet_addresses.json b/deployments/bscmainnet_addresses.json index 7767f5fa2..a8b7e55e6 100644 --- a/deployments/bscmainnet_addresses.json +++ b/deployments/bscmainnet_addresses.json @@ -34,7 +34,7 @@ "Liquidator_Implementation": "0xE26cE9b5FDd602225cCcC4cef7FAE596Dcf2A965", "Liquidator_Proxy": "0x0870793286aada55d39ce7f82fb2766e8004cf43", "MATIC": "0xCC42724C6683B7E57334c4E856f4c9965ED682bD", - "MarketFacet": "0x9622522d94BdEe9b1d7C2CD944e3ed74B33BD9Cf", + "MarketFacet": "0x4b093a3299F39615bA6b34B7897FDedCe7b83D63", "MoveDebtDelegate": "0x89621C48EeC04A85AfadFD37d32077e65aFe2226", "MoveDebtDelegate_Implementation": "0x8439932C45e646FcC1009690417A65BF48f68Ce7", "MoveDebtDelegate_Proxy": "0x89621C48EeC04A85AfadFD37d32077e65aFe2226", @@ -42,7 +42,7 @@ "PegStability_USDT": "0xC138aa4E424D1A8539e8F38Af5a754a2B7c3Cc36", "PegStability_USDT_Implementation": "0x9664568e5131e85f67d87fCD55B249F5D25fa43e", "PegStability_USDT_Proxy": "0xC138aa4E424D1A8539e8F38Af5a754a2B7c3Cc36", - "PolicyFacet": "0x95CC56f266BC95Ae2486cb0cFeda1054B4aA4086", + "PolicyFacet": "0x93e7Ff7c87B496aE76fFb22d437c9d46461A9B51", "Prime": "0xBbCD063efE506c3D42a0Fa2dB5C08430288C71FC", "PrimeLiquidityProvider": "0x23c4F844ffDdC6161174eB32c770D4D8C07833F2", "PrimeLiquidityProvider_Implementation": "0x208068AE8A619FCc851659791659B1aA40d796dA", @@ -51,7 +51,7 @@ "Prime_Proxy": "0xBbCD063efE506c3D42a0Fa2dB5C08430288C71FC", "RewardFacet": "0xc2F6bDCEa4907E8CB7480d3d315bc01c125fb63C", "SXP": "0x47BEAd2563dCBf3bF2c9407fEa4dC236fAbA485A", - "SetterFacet": "0x7dc9E7b21a9E343f4AD926b8B00Cff5adf5c1CdE", + "SetterFacet": "0x9B0D9D7c50d90f23449c4BbCAA671Ce7cd19DbCf", "SnapshotLens": "0x9802448Af040DA880Bf51bCbe4f2A4205ebC6d2C", "SwapRouterCorePool": "0x8938E6dA30b59c1E27d5f70a94688A89F7c815a4", "TRX": "0xCE7de646e7208a4Ef112cb6ed5038FA6cC6b12e3", diff --git a/deployments/bsctestnet.json b/deployments/bsctestnet.json index d44468171..f73c63485 100644 --- a/deployments/bsctestnet.json +++ b/deployments/bsctestnet.json @@ -4520,7 +4520,7 @@ ] }, "MarketFacet": { - "address": "0xF2F2aE5480c4527787Fb7Cde1Ed9A3EdfD40A60d", + "address": "0x00a949FfDa9B216fBA9C4E5b40ef561Af0FDb723", "abi": [ { "anonymous": false, @@ -4636,6 +4636,19 @@ "name": "MarketListed", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketUnlisted", + "type": "event" + }, { "constant": false, "inputs": [ @@ -5413,6 +5426,27 @@ "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "unlistMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ @@ -7826,7 +7860,7 @@ ] }, "PolicyFacet": { - "address": "0x7b17b28687B817158c20e3d1bf100106fBE794cf", + "address": "0x085C8d0133291348004AabFfbE7CAc2097aF2aa1", "abi": [ { "anonymous": false, @@ -18178,7 +18212,7 @@ ] }, "SetterFacet": { - "address": "0xaBdE9599a4aEcE4fEC59fBF2b8445149bc8B2c70", + "address": "0x490DFD07f592452307817C4283866035BDb3b275", "abi": [ { "anonymous": false, diff --git a/deployments/bsctestnet/MarketFacet.json b/deployments/bsctestnet/MarketFacet.json index 4e8f7cb8c..5639346ed 100644 --- a/deployments/bsctestnet/MarketFacet.json +++ b/deployments/bsctestnet/MarketFacet.json @@ -1,5 +1,5 @@ { - "address": "0xF2F2aE5480c4527787Fb7Cde1Ed9A3EdfD40A60d", + "address": "0x00a949FfDa9B216fBA9C4E5b40ef561Af0FDb723", "abi": [ { "anonymous": false, @@ -115,6 +115,19 @@ "name": "MarketListed", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketUnlisted", + "type": "event" + }, { "constant": false, "inputs": [ @@ -892,6 +905,27 @@ "stateMutability": "view", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "unlistMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ @@ -1155,28 +1189,28 @@ "type": "function" } ], - "transactionHash": "0x67723c0eddb93856b5ce99ed119a517a6064c939a9cc33f9c6e58912a0b88cda", + "transactionHash": "0xeb13de5cf6839e283f78e9d272e2ba5afbd681c59c760fd7ea7d1c5f8396764d", "receipt": { "to": null, - "from": "0x7Bf1Fe2C42E79dbA813Bf5026B7720935a55ec5f", - "contractAddress": "0xF2F2aE5480c4527787Fb7Cde1Ed9A3EdfD40A60d", - "transactionIndex": 5, - "gasUsed": "1665799", + "from": "0x464779C41C5f1Be598853C1F87bCC7087Ea75f28", + "contractAddress": "0x00a949FfDa9B216fBA9C4E5b40ef561Af0FDb723", + "transactionIndex": 2, + "gasUsed": "2025920", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x35a76482aeb199f0445a653a7bfec3af536c2c41f073f405be5b8d09a11011af", - "transactionHash": "0x67723c0eddb93856b5ce99ed119a517a6064c939a9cc33f9c6e58912a0b88cda", + "blockHash": "0x7ca06cb96a7d806eb98666aa760dfcaa836b680e3baabd0d4b0f2152cfe2b80c", + "transactionHash": "0xeb13de5cf6839e283f78e9d272e2ba5afbd681c59c760fd7ea7d1c5f8396764d", "logs": [], - "blockNumber": 38507138, - "cumulativeGasUsed": "2171884", + "blockNumber": 40555529, + "cumulativeGasUsed": "2367487", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "506bbeed5e5814c0309e06940945462d", - "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"DelegateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketExited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketListed\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"_supportMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"checkMembership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"vTokens\",\"type\":\"address[]\"}],\"name\":\"enterMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenAddress\",\"type\":\"address\"}],\"name\":\"exitMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAllMarkets\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAssetsIn\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isComptroller\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateCalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateVAICalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"updateDelegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the methods related to the market's management in the pool\",\"methods\":{\"_supportMarket(address)\":{\"details\":\"Allows a privileged role to add and list markets to the Comptroller\",\"params\":{\"vToken\":\"The address of the market (token) to list\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"checkMembership(address,address)\":{\"params\":{\"account\":\"The address of the account to check\",\"vToken\":\"The vToken to check\"},\"return\":\"True if the account is in the asset, otherwise false\"},\"enterMarkets(address[])\":{\"params\":{\"vTokens\":\"The list of addresses of the vToken markets to be enabled\"},\"return\":\"Success indicator for whether each corresponding market was entered\"},\"exitMarket(address)\":{\"details\":\"Sender must not have an outstanding borrow balance in the asset, or be providing necessary collateral for an outstanding borrow\",\"params\":{\"vTokenAddress\":\"The address of the asset to be removed\"},\"return\":\"Whether or not the account successfully exited the market\"},\"getAllMarkets()\":{\"details\":\"The automatic getter may be used to access an individual market\",\"return\":\"The list of market addresses\"},\"getAssetsIn(address)\":{\"params\":{\"account\":\"The address of the account to pull assets for\"},\"return\":\"A dynamic list with the assets the account has entered\"},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"details\":\"Used in liquidation (called in vToken.liquidateBorrowFresh)\",\"params\":{\"actualRepayAmount\":\"The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\",\"vTokenBorrowed\":\"The address of the borrowed vToken\",\"vTokenCollateral\":\"The address of the collateral vToken\"},\"return\":\"(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\"},\"liquidateVAICalculateSeizeTokens(address,uint256)\":{\"details\":\"Used in liquidation (called in vToken.liquidateBorrowFresh)\",\"params\":{\"actualRepayAmount\":\"The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\",\"vTokenCollateral\":\"The address of the collateral vToken\"},\"return\":\"(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\"},\"updateDelegate(address,bool)\":{\"params\":{\"approved\":\"Whether to grant (true) or revoke (false) the borrowing or redeeming rights\",\"delegate\":\"The address to update the rights for\"}}},\"title\":\"MarketFacet\"},\"userdoc\":{\"methods\":{\"_supportMarket(address)\":{\"notice\":\"Add the market to the markets mapping and set it as listed\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"checkMembership(address,address)\":{\"notice\":\"Returns whether the given account is entered in the given asset\"},\"enterMarkets(address[])\":{\"notice\":\"Add assets to be included in account liquidity calculation\"},\"exitMarket(address)\":{\"notice\":\"Removes asset from sender's account liquidity calculation\"},\"getAllMarkets()\":{\"notice\":\"Return all of the markets\"},\"getAssetsIn(address)\":{\"notice\":\"Returns the assets an account has entered\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"isComptroller()\":{\"notice\":\"Indicator that this is a Comptroller contract (for inspection)\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"liquidateVAICalculateSeizeTokens(address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"updateDelegate(address,bool)\":{\"notice\":\"Grants or revokes the borrowing or redeeming delegate rights to / from an account If allowed, the delegate will be able to borrow funds on behalf of the sender Upon a delegated borrow, the delegate will receive the funds, and the borrower will see the debt on their account Upon a delegated redeem, the delegate will receive the redeemed amount and the approver will see a deduction in his vToken balance\"}},\"notice\":\"This facet contract contains functions regarding markets\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/MarketFacet.sol\":\"MarketFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0xab3aca949ad85c46d8b7866330594282136109adbdab301d447108a8551e3dc3\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which corresponds to unlimited borrowing.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x13aa5a019c0ea5149d00480b5a3e1281ec316f8d159c52705f45b4c75a5abcb8\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/MarketFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { IMarketFacet } from \\\"../interfaces/IMarketFacet.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\n/**\\n * @title MarketFacet\\n * @author Venus\\n * @dev This facet contains all the methods related to the market's management in the pool\\n * @notice This facet contract contains functions regarding markets\\n */\\ncontract MarketFacet is IMarketFacet, FacetBase {\\n /// @notice Emitted when an admin supports a market\\n event MarketListed(VToken indexed vToken);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account\\n event DelegateUpdated(address indexed approver, address indexed delegate, bool approved);\\n\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n function isComptroller() public pure returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Returns the assets an account has entered\\n * @param account The address of the account to pull assets for\\n * @return A dynamic list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n return accountAssets[account];\\n }\\n\\n /**\\n * @notice Return all of the markets\\n * @dev The automatic getter may be used to access an individual market\\n * @return The list of market addresses\\n */\\n function getAllMarkets() external view returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n * @param vTokenBorrowed The address of the borrowed vToken\\n * @param vTokenCollateral The address of the collateral vToken\\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256) {\\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateCalculateSeizeTokens(\\n address(this),\\n vTokenBorrowed,\\n vTokenCollateral,\\n actualRepayAmount\\n );\\n return (err, seizeTokens);\\n }\\n\\n /**\\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n * @param vTokenCollateral The address of the collateral vToken\\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\\n */\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256) {\\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateVAICalculateSeizeTokens(\\n address(this),\\n vTokenCollateral,\\n actualRepayAmount\\n );\\n return (err, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in the given asset\\n * @param account The address of the account to check\\n * @param vToken The vToken to check\\n * @return True if the account is in the asset, otherwise false\\n */\\n function checkMembership(address account, VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].accountMembership[account];\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return Success indicator for whether each corresponding market was entered\\n */\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n results[i] = uint256(addToMarketInternal(VToken(vTokens[i]), msg.sender));\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation\\n * @dev Sender must not have an outstanding borrow balance in the asset,\\n * or be providing necessary collateral for an outstanding borrow\\n * @param vTokenAddress The address of the asset to be removed\\n * @return Whether or not the account successfully exited the market\\n */\\n function exitMarket(address vTokenAddress) external returns (uint256) {\\n checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 oErr, uint256 tokensHeld, uint256 amountOwed, ) = vToken.getAccountSnapshot(msg.sender);\\n require(oErr == 0, \\\"getAccountSnapshot failed\\\"); // semi-opaque error code\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED);\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n uint256 allowed = redeemAllowedInternal(vTokenAddress, msg.sender, tokensHeld);\\n if (allowed != 0) {\\n return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed);\\n }\\n\\n Market storage marketToExit = markets[address(vToken)];\\n\\n /* Return true if the sender is not already \\u2018in\\u2019 the market */\\n if (!marketToExit.accountMembership[msg.sender]) {\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /* Set vToken account membership to false */\\n delete marketToExit.accountMembership[msg.sender];\\n\\n /* Delete vToken from the account\\u2019s list of assets */\\n // In order to delete vToken, copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n uint256 i;\\n for (; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n userAssetList[i] = userAssetList[len - 1];\\n userAssetList.length--;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(i < len);\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Allows a privileged role to add and list markets to the Comptroller\\n * @param vToken The address of the market (token) to list\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function _supportMarket(VToken vToken) external returns (uint256) {\\n ensureAllowed(\\\"_supportMarket(address)\\\");\\n\\n if (markets[address(vToken)].isListed) {\\n return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS);\\n }\\n\\n vToken.isVToken(); // Sanity check to make sure its really a VToken\\n\\n // Note that isVenus is not in active use anymore\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.isVenus = false;\\n newMarket.collateralFactorMantissa = 0;\\n\\n _addMarketInternal(vToken);\\n _initializeMarket(address(vToken));\\n\\n emit MarketListed(vToken);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account\\n * If allowed, the delegate will be able to borrow funds on behalf of the sender\\n * Upon a delegated borrow, the delegate will receive the funds, and the borrower\\n * will see the debt on their account\\n * Upon a delegated redeem, the delegate will receive the redeemed amount and the approver\\n * will see a deduction in his vToken balance\\n * @param delegate The address to update the rights for\\n * @param approved Whether to grant (true) or revoke (false) the borrowing or redeeming rights\\n */\\n function updateDelegate(address delegate, bool approved) external {\\n ensureNonzeroAddress(delegate);\\n require(approvedDelegates[msg.sender][delegate] != approved, \\\"Delegation status unchanged\\\");\\n\\n _updateDelegate(msg.sender, delegate, approved);\\n }\\n\\n function _updateDelegate(address approver, address delegate, bool approved) internal {\\n approvedDelegates[approver][delegate] = approved;\\n emit DelegateUpdated(approver, delegate, approved);\\n }\\n\\n function _addMarketInternal(VToken vToken) internal {\\n uint256 allMarketsLength = allMarkets.length;\\n for (uint256 i; i < allMarketsLength; ++i) {\\n require(allMarkets[i] != vToken, \\\"already added\\\");\\n }\\n allMarkets.push(vToken);\\n }\\n\\n function _initializeMarket(address vToken) internal {\\n uint32 blockNumber = getBlockNumberAsUint32();\\n\\n VenusMarketState storage supplyState = venusSupplyState[vToken];\\n VenusMarketState storage borrowState = venusBorrowState[vToken];\\n\\n /*\\n * Update market state indices\\n */\\n if (supplyState.index == 0) {\\n // Initialize supply state index with default value\\n supplyState.index = venusInitialIndex;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = venusInitialIndex;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n }\\n}\\n\",\"keccak256\":\"0x22b5fdac3e46d3e39472dc7186119d89df9af7b1b0a7b9186f66eae217c07170\"},\"contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface IMarketFacet {\\n function isComptroller() external pure returns (bool);\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256);\\n\\n function checkMembership(address account, VToken vToken) external view returns (bool);\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n function _supportMarket(VToken vToken) external returns (uint256);\\n\\n function getAssetsIn(address account) external view returns (VToken[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function updateDelegate(address delegate, bool allowBorrows) external;\\n}\\n\",\"keccak256\":\"0x95adef906110bb671f5945799498419905290a267e4da26ac838bfbfbd44dd57\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function getVAIAddress() public view returns (address);\\n\\n function getMintableVAI(address minter) public view returns (uint, uint);\\n\\n function mintVAI(address minter, uint mintVAIAmount) external returns (uint);\\n\\n function repayVAI(address repayer, uint repayVAIAmount) external returns (uint);\\n\\n function liquidateVAI(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint, uint);\\n\\n function _initializeVenusVAIState(uint blockNumber) external returns (uint);\\n\\n function updateVenusVAIMintIndex() external returns (uint);\\n\\n function calcDistributeVAIMinterVenus(address vaiMinter) external returns (uint, uint, uint, uint);\\n\\n function getVAIRepayAmount(address account) public view returns (uint);\\n}\\n\",\"keccak256\":\"0x17eb6edb1262c4effcad86f614ff20d00256278485054b11aa5cf011ff6f8a86\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0xc77c4dd91f93f778c5048fa0e68cc0cad2fd4a308add54f0172c507858ce06c8\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611d2a806100206000396000f3fe608060405234801561001057600080fd5b50600436106103415760003560e01c80639bb27d62116101b8578063c5b4db5511610104578063e37d4b79116100a2578063ede4edd01161007c578063ede4edd014610929578063f445d7031461094f578063f851a4401461097d578063fa6331d81461098557610341565b8063e37d4b79146108cc578063e85a2960146108f2578063e87554461461092157610341565b8063d3270f99116100de578063d3270f9914610860578063dce1544914610868578063dcfbc0c714610894578063ddbf54fd1461089c57610341565b8063c5b4db551461082c578063c5f956af14610850578063c7ee005e1461085857610341565b8063b8324c7c11610171578063bec04f721161014b578063bec04f7214610776578063bf32442d1461077e578063c299823814610786578063c488847b146107f657610341565b8063b8324c7c146106fa578063bb82aa5e14610748578063bbb8864a1461075057610341565b80639bb27d6214610601578063a76b3fda14610609578063a78dc7751461062f578063abfceffc14610674578063b0772d0b146106ea578063b2eafc39146106f257610341565b80634a584432116102925780637dc0d1d0116102305780638e8f294b1161020a5780638e8f294b1461057b5780639254f5e5146105c3578063929fe9a1146105cb57806394b2294b146105f957610341565b80637dc0d1d0146105275780638a7dc1651461052f5780638c1ac18a1461055557610341565b80635dd3fc9d1161026c5780635dd3fc9d146104e9578063719f701b1461050f57806376551383146105175780637d172bd51461051f57610341565b80634a5844321461049e5780634ada90af146104c457806352d84d1e146104cc57610341565b806321af4569116102ff5780632bc7e29e116102d95780632bc7e29e1461043a5780634088c73e1461046057806341a18d2c14610468578063425fad581461049657610341565b806321af45691461040657806324a3d6221461042a578063267822471461043257610341565b80627e3dd21461034657806302c3bcbb1461036257806304ef9d581461039a57806308e0225c146103a25780630db4b4e5146103d057806310b98338146103d8575b600080fd5b61034e61098d565b604080519115158252519081900360200190f35b6103886004803603602081101561037857600080fd5b50356001600160a01b0316610993565b60408051918252519081900360200190f35b6103886109a5565b610388600480360360408110156103b857600080fd5b506001600160a01b03813581169160200135166109ab565b6103886109c8565b61034e600480360360408110156103ee57600080fd5b506001600160a01b03813581169160200135166109ce565b61040e6109ee565b604080516001600160a01b039092168252519081900360200190f35b61040e6109fd565b61040e610a0c565b6103886004803603602081101561045057600080fd5b50356001600160a01b0316610a1b565b61034e610a2d565b6103886004803603604081101561047e57600080fd5b506001600160a01b0381358116916020013516610a36565b61034e610a53565b610388600480360360208110156104b457600080fd5b50356001600160a01b0316610a62565b610388610a74565b61040e600480360360208110156104e257600080fd5b5035610a7a565b610388600480360360208110156104ff57600080fd5b50356001600160a01b0316610aa1565b610388610ab3565b61034e610ab9565b61040e610ac7565b61040e610ad6565b6103886004803603602081101561054557600080fd5b50356001600160a01b0316610ae5565b61034e6004803603602081101561056b57600080fd5b50356001600160a01b0316610af7565b6105a16004803603602081101561059157600080fd5b50356001600160a01b0316610b0c565b6040805193151584526020840192909252151582820152519081900360600190f35b61040e610b32565b61034e600480360360408110156105e157600080fd5b506001600160a01b0381358116916020013516610b41565b610388610b75565b61040e610b7b565b6103886004803603602081101561061f57600080fd5b50356001600160a01b0316610b8a565b61065b6004803603604081101561064557600080fd5b506001600160a01b038135169060200135610cec565b6040805192835260208301919091528051918290030190f35b61069a6004803603602081101561068a57600080fd5b50356001600160a01b0316610d8b565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106d65781810151838201526020016106be565b505050509050019250505060405180910390f35b61069a610e01565b61040e610e63565b6107206004803603602081101561071057600080fd5b50356001600160a01b0316610e72565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61040e610e9c565b6103886004803603602081101561076657600080fd5b50356001600160a01b0316610eab565b610388610ebd565b61040e610ec3565b61069a6004803603602081101561079c57600080fd5b8101906020810181356401000000008111156107b757600080fd5b8201836020820111156107c957600080fd5b803590602001918460208302840111640100000000831117156107eb57600080fd5b509092509050610ed2565b61065b6004803603606081101561080c57600080fd5b506001600160a01b03813581169160208101359091169060400135610f68565b610834611010565b604080516001600160e01b039092168252519081900360200190f35b61040e611023565b61040e611032565b61040e611041565b61040e6004803603604081101561087e57600080fd5b506001600160a01b038135169060200135611050565b61040e611085565b6108ca600480360360408110156108b257600080fd5b506001600160a01b0381351690602001351515611094565b005b610720600480360360208110156108e257600080fd5b50356001600160a01b031661112b565b61034e6004803603604081101561090857600080fd5b5080356001600160a01b0316906020013560ff16611155565b610388611195565b6103886004803603602081101561093f57600080fd5b50356001600160a01b031661119b565b61034e6004803603604081101561096557600080fd5b506001600160a01b0381358116916020013516611445565b61040e611465565b610388611474565b60015b90565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b600d8181548110610a8757fe5b6000918252602090912001546001600160a01b0316905081565b602b6020526000908152604090205481565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff165b92915050565b60075481565b6025546001600160a01b031681565b6000610bca6040518060400160405280601781526020017f5f737570706f72744d61726b657428616464726573732900000000000000000081525061147a565b6001600160a01b03821660009081526009602052604090205460ff1615610bfe57610bf7600a601161159e565b9050610ce7565b816001600160a01b0316633d9ea3a16040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3757600080fd5b505afa158015610c4b573d6000803e3d6000fd5b505050506040513d6020811015610c6157600080fd5b50506001600160a01b03821660009081526009602052604081208054600160ff1991821681178355600383018054909216909155810191909155610ca48361160b565b610cad836116e4565b6040516001600160a01b038416907fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90600090a260009150505b919050565b602654604080516304f65f8b60e21b81523060048201526001600160a01b038581166024830152604482018590528251600094859485948594909216926313d97e2c926064808201939291829003018186803b158015610d4b57600080fd5b505afa158015610d5f573d6000803e3d6000fd5b505050506040513d6040811015610d7557600080fd5b5080516020909101519097909650945050505050565b6001600160a01b038116600090815260086020908152604091829020805483518184028101840190945280845260609392830182828015610df557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dd7575b50505050509050919050565b6060600d805480602002602001604051908101604052809291908181526020018280548015610e5957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e3b575b5050505050905090565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b60408051828152602080840282010190915260609082908290828015610f02578160200160208202803883390190505b50905060005b82811015610f5f57610f35868683818110610f1f57fe5b905060200201356001600160a01b0316336117a1565b6013811115610f4057fe5b828281518110610f4c57fe5b6020908102919091010152600101610f08565b50949350505050565b60265460408051630779996560e11b81523060048201526001600160a01b038681166024830152858116604483015260648201859052825160009485948594859490921692630ef332ca926084808201939291829003018186803b158015610fcf57600080fd5b505afa158015610fe3573d6000803e3d6000fd5b505050506040513d6040811015610ff957600080fd5b508051602090910151909890975095505050505050565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b6026546001600160a01b031681565b6008602052816000526040600020818154811061106957fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b61109d82611885565b336000908152602c602090815260408083206001600160a01b038616845290915290205460ff161515811515141561111c576040805162461bcd60e51b815260206004820152601b60248201527f44656c65676174696f6e2073746174757320756e6368616e6765640000000000604482015290519081900360640190fd5b6111273383836118d8565b5050565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526029602052604081208183600881111561117a57fe5b815260208101919091526040016000205460ff169392505050565b60055481565b60006111a8826008611946565b604080516361bfb47160e11b815233600482015290518391600091829182916001600160a01b0386169163c37f68e2916024808301926080929190829003018186803b1580156111f757600080fd5b505afa15801561120b573d6000803e3d6000fd5b505050506040513d608081101561122157600080fd5b50805160208201516040909201519094509092509050821561128a576040805162461bcd60e51b815260206004820152601960248201527f6765744163636f756e74536e617073686f74206661696c656400000000000000604482015290519081900360640190fd5b80156112a75761129c600c600261159e565b945050505050610ce7565b60006112b4873385611995565b905080156112d5576112c9600e600383611a48565b95505050505050610ce7565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff166113145760009650505050505050610ce7565b3360009081526002820160209081526040808320805460ff1916905560089091528120805490915b818110156113f557886001600160a01b031683828154811061135a57fe5b6000918252602090912001546001600160a01b031614156113ed5782600183038154811061138457fe5b9060005260206000200160009054906101000a90046001600160a01b03168382815481106113ae57fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905582546113e7846000198301611cae565b506113f5565b60010161133c565b8181106113fe57fe5b60405133906001600160a01b038b16907fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90600090a360009b9a5050505050505050505050565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156114e35781810151838201526020016114cb565b50505050905090810190601f1680156115105780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561152e57600080fd5b505afa158015611542573d6000803e3d6000fd5b505050506040513d602081101561155857600080fd5b505161159b576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360138111156115cd57fe5b8360178111156115d957fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561160457fe5b9392505050565b600d5460005b8181101561169057826001600160a01b0316600d828154811061163057fe5b6000918252602090912001546001600160a01b03161415611688576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b600101611611565b5050600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b60006116ee611ab6565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b03166117455781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b03166117745780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b60006117ae836007611946565b6001600160a01b03831660009081526009602052604090206117cf81611af7565b6001600160a01b038316600090815260028201602052604090205460ff16156117fc576000915050610b6f565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b6001600160a01b03811661159b576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b038381166000818152602c6020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fcb325b7784f78486e42849c7a50b8c5ee008d00cd90e108a58912c0fcb6288b49281900390910190a3505050565b6119508282611155565b15611127576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b03831660009081526009602052604081206119b690611af7565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166119ef57506000611604565b6000806119ff8587866000611b41565b91935090915060009050826013811115611a1557fe5b14611a2f57816013811115611a2657fe5b92505050611604565b8015611a3c576004611a26565b50600095945050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846013811115611a7757fe5b846017811115611a8357fe5b604080519283526020830191909152818101859052519081900360600190a1836013811115611aae57fe5b949350505050565b6000611af2611ac3611c0f565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b815250611c13565b905090565b805460ff1661159b576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b158015611bb457600080fd5b505afa158015611bc8573d6000803e3d6000fd5b505050506040513d6060811015611bde57600080fd5b50805160208201516040909201519094509092509050826013811115611c0057fe5b9a919950975095505050505050565b4390565b6000816401000000008410611ca65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c6b578181015183820152602001611c53565b50505050905090810190601f168015611c985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b815481835581811115611cd257600083815260209020611cd2918101908301611cd7565b505050565b61099091905b80821115611cf15760008155600101611cdd565b509056fea265627a7a72315820f632996f9702e42ca8eaa0859311c2e6557ca957e8fa39f6b1dffaa5173b84dd64736f6c63430005100032", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103415760003560e01c80639bb27d62116101b8578063c5b4db5511610104578063e37d4b79116100a2578063ede4edd01161007c578063ede4edd014610929578063f445d7031461094f578063f851a4401461097d578063fa6331d81461098557610341565b8063e37d4b79146108cc578063e85a2960146108f2578063e87554461461092157610341565b8063d3270f99116100de578063d3270f9914610860578063dce1544914610868578063dcfbc0c714610894578063ddbf54fd1461089c57610341565b8063c5b4db551461082c578063c5f956af14610850578063c7ee005e1461085857610341565b8063b8324c7c11610171578063bec04f721161014b578063bec04f7214610776578063bf32442d1461077e578063c299823814610786578063c488847b146107f657610341565b8063b8324c7c146106fa578063bb82aa5e14610748578063bbb8864a1461075057610341565b80639bb27d6214610601578063a76b3fda14610609578063a78dc7751461062f578063abfceffc14610674578063b0772d0b146106ea578063b2eafc39146106f257610341565b80634a584432116102925780637dc0d1d0116102305780638e8f294b1161020a5780638e8f294b1461057b5780639254f5e5146105c3578063929fe9a1146105cb57806394b2294b146105f957610341565b80637dc0d1d0146105275780638a7dc1651461052f5780638c1ac18a1461055557610341565b80635dd3fc9d1161026c5780635dd3fc9d146104e9578063719f701b1461050f57806376551383146105175780637d172bd51461051f57610341565b80634a5844321461049e5780634ada90af146104c457806352d84d1e146104cc57610341565b806321af4569116102ff5780632bc7e29e116102d95780632bc7e29e1461043a5780634088c73e1461046057806341a18d2c14610468578063425fad581461049657610341565b806321af45691461040657806324a3d6221461042a578063267822471461043257610341565b80627e3dd21461034657806302c3bcbb1461036257806304ef9d581461039a57806308e0225c146103a25780630db4b4e5146103d057806310b98338146103d8575b600080fd5b61034e61098d565b604080519115158252519081900360200190f35b6103886004803603602081101561037857600080fd5b50356001600160a01b0316610993565b60408051918252519081900360200190f35b6103886109a5565b610388600480360360408110156103b857600080fd5b506001600160a01b03813581169160200135166109ab565b6103886109c8565b61034e600480360360408110156103ee57600080fd5b506001600160a01b03813581169160200135166109ce565b61040e6109ee565b604080516001600160a01b039092168252519081900360200190f35b61040e6109fd565b61040e610a0c565b6103886004803603602081101561045057600080fd5b50356001600160a01b0316610a1b565b61034e610a2d565b6103886004803603604081101561047e57600080fd5b506001600160a01b0381358116916020013516610a36565b61034e610a53565b610388600480360360208110156104b457600080fd5b50356001600160a01b0316610a62565b610388610a74565b61040e600480360360208110156104e257600080fd5b5035610a7a565b610388600480360360208110156104ff57600080fd5b50356001600160a01b0316610aa1565b610388610ab3565b61034e610ab9565b61040e610ac7565b61040e610ad6565b6103886004803603602081101561054557600080fd5b50356001600160a01b0316610ae5565b61034e6004803603602081101561056b57600080fd5b50356001600160a01b0316610af7565b6105a16004803603602081101561059157600080fd5b50356001600160a01b0316610b0c565b6040805193151584526020840192909252151582820152519081900360600190f35b61040e610b32565b61034e600480360360408110156105e157600080fd5b506001600160a01b0381358116916020013516610b41565b610388610b75565b61040e610b7b565b6103886004803603602081101561061f57600080fd5b50356001600160a01b0316610b8a565b61065b6004803603604081101561064557600080fd5b506001600160a01b038135169060200135610cec565b6040805192835260208301919091528051918290030190f35b61069a6004803603602081101561068a57600080fd5b50356001600160a01b0316610d8b565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106d65781810151838201526020016106be565b505050509050019250505060405180910390f35b61069a610e01565b61040e610e63565b6107206004803603602081101561071057600080fd5b50356001600160a01b0316610e72565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61040e610e9c565b6103886004803603602081101561076657600080fd5b50356001600160a01b0316610eab565b610388610ebd565b61040e610ec3565b61069a6004803603602081101561079c57600080fd5b8101906020810181356401000000008111156107b757600080fd5b8201836020820111156107c957600080fd5b803590602001918460208302840111640100000000831117156107eb57600080fd5b509092509050610ed2565b61065b6004803603606081101561080c57600080fd5b506001600160a01b03813581169160208101359091169060400135610f68565b610834611010565b604080516001600160e01b039092168252519081900360200190f35b61040e611023565b61040e611032565b61040e611041565b61040e6004803603604081101561087e57600080fd5b506001600160a01b038135169060200135611050565b61040e611085565b6108ca600480360360408110156108b257600080fd5b506001600160a01b0381351690602001351515611094565b005b610720600480360360208110156108e257600080fd5b50356001600160a01b031661112b565b61034e6004803603604081101561090857600080fd5b5080356001600160a01b0316906020013560ff16611155565b610388611195565b6103886004803603602081101561093f57600080fd5b50356001600160a01b031661119b565b61034e6004803603604081101561096557600080fd5b506001600160a01b0381358116916020013516611445565b61040e611465565b610388611474565b60015b90565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b600d8181548110610a8757fe5b6000918252602090912001546001600160a01b0316905081565b602b6020526000908152604090205481565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff165b92915050565b60075481565b6025546001600160a01b031681565b6000610bca6040518060400160405280601781526020017f5f737570706f72744d61726b657428616464726573732900000000000000000081525061147a565b6001600160a01b03821660009081526009602052604090205460ff1615610bfe57610bf7600a601161159e565b9050610ce7565b816001600160a01b0316633d9ea3a16040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3757600080fd5b505afa158015610c4b573d6000803e3d6000fd5b505050506040513d6020811015610c6157600080fd5b50506001600160a01b03821660009081526009602052604081208054600160ff1991821681178355600383018054909216909155810191909155610ca48361160b565b610cad836116e4565b6040516001600160a01b038416907fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90600090a260009150505b919050565b602654604080516304f65f8b60e21b81523060048201526001600160a01b038581166024830152604482018590528251600094859485948594909216926313d97e2c926064808201939291829003018186803b158015610d4b57600080fd5b505afa158015610d5f573d6000803e3d6000fd5b505050506040513d6040811015610d7557600080fd5b5080516020909101519097909650945050505050565b6001600160a01b038116600090815260086020908152604091829020805483518184028101840190945280845260609392830182828015610df557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610dd7575b50505050509050919050565b6060600d805480602002602001604051908101604052809291908181526020018280548015610e5957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e3b575b5050505050905090565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b60408051828152602080840282010190915260609082908290828015610f02578160200160208202803883390190505b50905060005b82811015610f5f57610f35868683818110610f1f57fe5b905060200201356001600160a01b0316336117a1565b6013811115610f4057fe5b828281518110610f4c57fe5b6020908102919091010152600101610f08565b50949350505050565b60265460408051630779996560e11b81523060048201526001600160a01b038681166024830152858116604483015260648201859052825160009485948594859490921692630ef332ca926084808201939291829003018186803b158015610fcf57600080fd5b505afa158015610fe3573d6000803e3d6000fd5b505050506040513d6040811015610ff957600080fd5b508051602090910151909890975095505050505050565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b6026546001600160a01b031681565b6008602052816000526040600020818154811061106957fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b61109d82611885565b336000908152602c602090815260408083206001600160a01b038616845290915290205460ff161515811515141561111c576040805162461bcd60e51b815260206004820152601b60248201527f44656c65676174696f6e2073746174757320756e6368616e6765640000000000604482015290519081900360640190fd5b6111273383836118d8565b5050565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526029602052604081208183600881111561117a57fe5b815260208101919091526040016000205460ff169392505050565b60055481565b60006111a8826008611946565b604080516361bfb47160e11b815233600482015290518391600091829182916001600160a01b0386169163c37f68e2916024808301926080929190829003018186803b1580156111f757600080fd5b505afa15801561120b573d6000803e3d6000fd5b505050506040513d608081101561122157600080fd5b50805160208201516040909201519094509092509050821561128a576040805162461bcd60e51b815260206004820152601960248201527f6765744163636f756e74536e617073686f74206661696c656400000000000000604482015290519081900360640190fd5b80156112a75761129c600c600261159e565b945050505050610ce7565b60006112b4873385611995565b905080156112d5576112c9600e600383611a48565b95505050505050610ce7565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff166113145760009650505050505050610ce7565b3360009081526002820160209081526040808320805460ff1916905560089091528120805490915b818110156113f557886001600160a01b031683828154811061135a57fe5b6000918252602090912001546001600160a01b031614156113ed5782600183038154811061138457fe5b9060005260206000200160009054906101000a90046001600160a01b03168382815481106113ae57fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905582546113e7846000198301611cae565b506113f5565b60010161133c565b8181106113fe57fe5b60405133906001600160a01b038b16907fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90600090a360009b9a5050505050505050505050565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156114e35781810151838201526020016114cb565b50505050905090810190601f1680156115105780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561152e57600080fd5b505afa158015611542573d6000803e3d6000fd5b505050506040513d602081101561155857600080fd5b505161159b576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08360138111156115cd57fe5b8360178111156115d957fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561160457fe5b9392505050565b600d5460005b8181101561169057826001600160a01b0316600d828154811061163057fe5b6000918252602090912001546001600160a01b03161415611688576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b600101611611565b5050600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b60006116ee611ab6565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b03166117455781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b03166117745780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b60006117ae836007611946565b6001600160a01b03831660009081526009602052604090206117cf81611af7565b6001600160a01b038316600090815260028201602052604090205460ff16156117fc576000915050610b6f565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b6001600160a01b03811661159b576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b038381166000818152602c6020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fcb325b7784f78486e42849c7a50b8c5ee008d00cd90e108a58912c0fcb6288b49281900390910190a3505050565b6119508282611155565b15611127576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b03831660009081526009602052604081206119b690611af7565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166119ef57506000611604565b6000806119ff8587866000611b41565b91935090915060009050826013811115611a1557fe5b14611a2f57816013811115611a2657fe5b92505050611604565b8015611a3c576004611a26565b50600095945050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0846013811115611a7757fe5b846017811115611a8357fe5b604080519283526020830191909152818101859052519081900360600190a1836013811115611aae57fe5b949350505050565b6000611af2611ac3611c0f565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b815250611c13565b905090565b805460ff1661159b576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b158015611bb457600080fd5b505afa158015611bc8573d6000803e3d6000fd5b505050506040513d6060811015611bde57600080fd5b50805160208201516040909201519094509092509050826013811115611c0057fe5b9a919950975095505050505050565b4390565b6000816401000000008410611ca65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c6b578181015183820152602001611c53565b50505050905090810190601f168015611c985780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b815481835581811115611cd257600083815260209020611cd2918101908301611cd7565b505050565b61099091905b80821115611cf15760008155600101611cdd565b509056fea265627a7a72315820f632996f9702e42ca8eaa0859311c2e6557ca957e8fa39f6b1dffaa5173b84dd64736f6c63430005100032", + "numDeployments": 5, + "solcInputHash": "7674fc0eb5134fe9ab2419cd8945df4b", + "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"DelegateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketExited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketListed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"MarketUnlisted\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"_supportMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"checkMembership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"vTokens\",\"type\":\"address[]\"}],\"name\":\"enterMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenAddress\",\"type\":\"address\"}],\"name\":\"exitMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAllMarkets\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAssetsIn\",\"outputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isComptroller\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateCalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateVAICalculateSeizeTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"}],\"name\":\"unlistMarket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"updateDelegate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the methods related to the market's management in the pool\",\"methods\":{\"_supportMarket(address)\":{\"details\":\"Allows a privileged role to add and list markets to the Comptroller\",\"params\":{\"vToken\":\"The address of the market (token) to list\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"checkMembership(address,address)\":{\"params\":{\"account\":\"The address of the account to check\",\"vToken\":\"The vToken to check\"},\"return\":\"True if the account is in the asset, otherwise false\"},\"enterMarkets(address[])\":{\"params\":{\"vTokens\":\"The list of addresses of the vToken markets to be enabled\"},\"return\":\"Success indicator for whether each corresponding market was entered\"},\"exitMarket(address)\":{\"details\":\"Sender must not have an outstanding borrow balance in the asset, or be providing necessary collateral for an outstanding borrow\",\"params\":{\"vTokenAddress\":\"The address of the asset to be removed\"},\"return\":\"Whether or not the account successfully exited the market\"},\"getAllMarkets()\":{\"details\":\"The automatic getter may be used to access an individual market\",\"return\":\"The list of market addresses\"},\"getAssetsIn(address)\":{\"params\":{\"account\":\"The address of the account to pull assets for\"},\"return\":\"A dynamic list with the assets the account has entered\"},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"details\":\"Used in liquidation (called in vToken.liquidateBorrowFresh)\",\"params\":{\"actualRepayAmount\":\"The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\",\"vTokenBorrowed\":\"The address of the borrowed vToken\",\"vTokenCollateral\":\"The address of the collateral vToken\"},\"return\":\"(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\"},\"liquidateVAICalculateSeizeTokens(address,uint256)\":{\"details\":\"Used in liquidation (called in vToken.liquidateBorrowFresh)\",\"params\":{\"actualRepayAmount\":\"The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\",\"vTokenCollateral\":\"The address of the collateral vToken\"},\"return\":\"(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\"},\"unlistMarket(address)\":{\"details\":\"Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0\",\"params\":{\"market\":\"The address of the market (vToken) to unlist\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"updateDelegate(address,bool)\":{\"params\":{\"approved\":\"Whether to grant (true) or revoke (false) the borrowing or redeeming rights\",\"delegate\":\"The address to update the rights for\"}}},\"title\":\"MarketFacet\"},\"userdoc\":{\"methods\":{\"_supportMarket(address)\":{\"notice\":\"Add the market to the markets mapping and set it as listed\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"checkMembership(address,address)\":{\"notice\":\"Returns whether the given account is entered in the given asset\"},\"enterMarkets(address[])\":{\"notice\":\"Add assets to be included in account liquidity calculation\"},\"exitMarket(address)\":{\"notice\":\"Removes asset from sender's account liquidity calculation\"},\"getAllMarkets()\":{\"notice\":\"Return all of the markets\"},\"getAssetsIn(address)\":{\"notice\":\"Returns the assets an account has entered\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"isComptroller()\":{\"notice\":\"Indicator that this is a Comptroller contract (for inspection)\"},\"liquidateCalculateSeizeTokens(address,address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"liquidateVAICalculateSeizeTokens(address,uint256)\":{\"notice\":\"Calculate number of tokens of collateral asset to seize given an underlying amount\"},\"unlistMarket(address)\":{\"notice\":\"Unlist a market by setting isListed to false\"},\"updateDelegate(address,bool)\":{\"notice\":\"Grants or revokes the borrowing or redeeming delegate rights to / from an account If allowed, the delegate will be able to borrow funds on behalf of the sender Upon a delegated borrow, the delegate will receive the funds, and the borrower will see the debt on their account Upon a delegated redeem, the delegate will receive the redeemed amount and the approver will see a deduction in his vToken balance\"}},\"notice\":\"This facet contract contains functions regarding markets\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/MarketFacet.sol\":\"MarketFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x06608bb502e91c33fda8c0dd88cc79a49a078fab521bc27d10fc3a69c1da55f4\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/MarketFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { IMarketFacet } from \\\"../interfaces/IMarketFacet.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\n/**\\n * @title MarketFacet\\n * @author Venus\\n * @dev This facet contains all the methods related to the market's management in the pool\\n * @notice This facet contract contains functions regarding markets\\n */\\ncontract MarketFacet is IMarketFacet, FacetBase {\\n /// @notice Emitted when an admin supports a market\\n event MarketListed(VToken indexed vToken);\\n\\n /// @notice Emitted when an account exits a market\\n event MarketExited(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account\\n event DelegateUpdated(address indexed approver, address indexed delegate, bool approved);\\n\\n /// @notice Emitted when an admin unlists a market\\n event MarketUnlisted(address indexed vToken);\\n\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n function isComptroller() public pure returns (bool) {\\n return true;\\n }\\n\\n /**\\n * @notice Returns the assets an account has entered\\n * @param account The address of the account to pull assets for\\n * @return A dynamic list with the assets the account has entered\\n */\\n function getAssetsIn(address account) external view returns (VToken[] memory) {\\n uint256 len;\\n VToken[] memory _accountAssets = accountAssets[account];\\n uint256 _accountAssetsLength = _accountAssets.length;\\n\\n VToken[] memory assetsIn = new VToken[](_accountAssetsLength);\\n\\n for (uint256 i; i < _accountAssetsLength; ++i) {\\n Market memory market = markets[address(_accountAssets[i])];\\n if (market.isListed) {\\n assetsIn[len] = _accountAssets[i];\\n ++len;\\n }\\n }\\n\\n assembly {\\n mstore(assetsIn, len)\\n }\\n\\n return assetsIn;\\n }\\n\\n /**\\n * @notice Return all of the markets\\n * @dev The automatic getter may be used to access an individual market\\n * @return The list of market addresses\\n */\\n function getAllMarkets() external view returns (VToken[] memory) {\\n return allMarkets;\\n }\\n\\n /**\\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n * @param vTokenBorrowed The address of the borrowed vToken\\n * @param vTokenCollateral The address of the collateral vToken\\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\\n */\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256) {\\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateCalculateSeizeTokens(\\n address(this),\\n vTokenBorrowed,\\n vTokenCollateral,\\n actualRepayAmount\\n );\\n return (err, seizeTokens);\\n }\\n\\n /**\\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n * @param vTokenCollateral The address of the collateral vToken\\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\\n */\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256) {\\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateVAICalculateSeizeTokens(\\n address(this),\\n vTokenCollateral,\\n actualRepayAmount\\n );\\n return (err, seizeTokens);\\n }\\n\\n /**\\n * @notice Returns whether the given account is entered in the given asset\\n * @param account The address of the account to check\\n * @param vToken The vToken to check\\n * @return True if the account is in the asset, otherwise false\\n */\\n function checkMembership(address account, VToken vToken) external view returns (bool) {\\n return markets[address(vToken)].accountMembership[account];\\n }\\n\\n /**\\n * @notice Add assets to be included in account liquidity calculation\\n * @param vTokens The list of addresses of the vToken markets to be enabled\\n * @return Success indicator for whether each corresponding market was entered\\n */\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory) {\\n uint256 len = vTokens.length;\\n\\n uint256[] memory results = new uint256[](len);\\n for (uint256 i; i < len; ++i) {\\n results[i] = uint256(addToMarketInternal(VToken(vTokens[i]), msg.sender));\\n }\\n\\n return results;\\n }\\n\\n /**\\n * @notice Unlist a market by setting isListed to false\\n * @dev Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0\\n * @param market The address of the market (vToken) to unlist\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function unlistMarket(address market) external returns (uint256) {\\n ensureAllowed(\\\"unlistMarket(address)\\\");\\n\\n Market storage _market = markets[market];\\n\\n if (!_market.isListed) {\\n return fail(Error.MARKET_NOT_LISTED, FailureInfo.UNLIST_MARKET_NOT_LISTED);\\n }\\n\\n require(actionPaused(market, Action.BORROW), \\\"borrow action is not paused\\\");\\n require(actionPaused(market, Action.MINT), \\\"mint action is not paused\\\");\\n require(actionPaused(market, Action.REDEEM), \\\"redeem action is not paused\\\");\\n require(actionPaused(market, Action.REPAY), \\\"repay action is not paused\\\");\\n require(actionPaused(market, Action.ENTER_MARKET), \\\"enter market action is not paused\\\");\\n require(actionPaused(market, Action.LIQUIDATE), \\\"liquidate action is not paused\\\");\\n require(actionPaused(market, Action.SEIZE), \\\"seize action is not paused\\\");\\n require(actionPaused(market, Action.TRANSFER), \\\"transfer action is not paused\\\");\\n require(actionPaused(market, Action.EXIT_MARKET), \\\"exit market action is not paused\\\");\\n\\n require(borrowCaps[market] == 0, \\\"borrow cap is not 0\\\");\\n require(supplyCaps[market] == 0, \\\"supply cap is not 0\\\");\\n\\n require(_market.collateralFactorMantissa == 0, \\\"collateral factor is not 0\\\");\\n\\n _market.isListed = false;\\n emit MarketUnlisted(market);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Removes asset from sender's account liquidity calculation\\n * @dev Sender must not have an outstanding borrow balance in the asset,\\n * or be providing necessary collateral for an outstanding borrow\\n * @param vTokenAddress The address of the asset to be removed\\n * @return Whether or not the account successfully exited the market\\n */\\n function exitMarket(address vTokenAddress) external returns (uint256) {\\n checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n\\n VToken vToken = VToken(vTokenAddress);\\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n (uint256 oErr, uint256 tokensHeld, uint256 amountOwed, ) = vToken.getAccountSnapshot(msg.sender);\\n require(oErr == 0, \\\"getAccountSnapshot failed\\\"); // semi-opaque error code\\n\\n /* Fail if the sender has a borrow balance */\\n if (amountOwed != 0) {\\n return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED);\\n }\\n\\n /* Fail if the sender is not permitted to redeem all of their tokens */\\n uint256 allowed = redeemAllowedInternal(vTokenAddress, msg.sender, tokensHeld);\\n if (allowed != 0) {\\n return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed);\\n }\\n\\n Market storage marketToExit = markets[address(vToken)];\\n\\n /* Return true if the sender is not already \\u2018in\\u2019 the market */\\n if (!marketToExit.accountMembership[msg.sender]) {\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /* Set vToken account membership to false */\\n delete marketToExit.accountMembership[msg.sender];\\n\\n /* Delete vToken from the account\\u2019s list of assets */\\n // In order to delete vToken, copy last item in list to location of item to be removed, reduce length by 1\\n VToken[] storage userAssetList = accountAssets[msg.sender];\\n uint256 len = userAssetList.length;\\n uint256 i;\\n for (; i < len; ++i) {\\n if (userAssetList[i] == vToken) {\\n userAssetList[i] = userAssetList[len - 1];\\n userAssetList.length--;\\n break;\\n }\\n }\\n\\n // We *must* have found the asset in the list or our redundant data structure is broken\\n assert(i < len);\\n\\n emit MarketExited(vToken, msg.sender);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Add the market to the markets mapping and set it as listed\\n * @dev Allows a privileged role to add and list markets to the Comptroller\\n * @param vToken The address of the market (token) to list\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function _supportMarket(VToken vToken) external returns (uint256) {\\n ensureAllowed(\\\"_supportMarket(address)\\\");\\n\\n if (markets[address(vToken)].isListed) {\\n return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS);\\n }\\n\\n vToken.isVToken(); // Sanity check to make sure its really a VToken\\n\\n // Note that isVenus is not in active use anymore\\n Market storage newMarket = markets[address(vToken)];\\n newMarket.isListed = true;\\n newMarket.isVenus = false;\\n newMarket.collateralFactorMantissa = 0;\\n\\n _addMarketInternal(vToken);\\n _initializeMarket(address(vToken));\\n\\n emit MarketListed(vToken);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account\\n * If allowed, the delegate will be able to borrow funds on behalf of the sender\\n * Upon a delegated borrow, the delegate will receive the funds, and the borrower\\n * will see the debt on their account\\n * Upon a delegated redeem, the delegate will receive the redeemed amount and the approver\\n * will see a deduction in his vToken balance\\n * @param delegate The address to update the rights for\\n * @param approved Whether to grant (true) or revoke (false) the borrowing or redeeming rights\\n */\\n function updateDelegate(address delegate, bool approved) external {\\n ensureNonzeroAddress(delegate);\\n require(approvedDelegates[msg.sender][delegate] != approved, \\\"Delegation status unchanged\\\");\\n\\n _updateDelegate(msg.sender, delegate, approved);\\n }\\n\\n function _updateDelegate(address approver, address delegate, bool approved) internal {\\n approvedDelegates[approver][delegate] = approved;\\n emit DelegateUpdated(approver, delegate, approved);\\n }\\n\\n function _addMarketInternal(VToken vToken) internal {\\n uint256 allMarketsLength = allMarkets.length;\\n for (uint256 i; i < allMarketsLength; ++i) {\\n require(allMarkets[i] != vToken, \\\"already added\\\");\\n }\\n allMarkets.push(vToken);\\n }\\n\\n function _initializeMarket(address vToken) internal {\\n uint32 blockNumber = getBlockNumberAsUint32();\\n\\n VenusMarketState storage supplyState = venusSupplyState[vToken];\\n VenusMarketState storage borrowState = venusBorrowState[vToken];\\n\\n /*\\n * Update market state indices\\n */\\n if (supplyState.index == 0) {\\n // Initialize supply state index with default value\\n supplyState.index = venusInitialIndex;\\n }\\n\\n if (borrowState.index == 0) {\\n // Initialize borrow state index with default value\\n borrowState.index = venusInitialIndex;\\n }\\n\\n /*\\n * Update market state block numbers\\n */\\n supplyState.block = borrowState.block = blockNumber;\\n }\\n}\\n\",\"keccak256\":\"0x23d2725adb9b5eea4fc90f9a7a57e43654d906eaeebb69fcec5a8b7aafc07ebd\"},\"contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface IMarketFacet {\\n function isComptroller() external pure returns (bool);\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint256 actualRepayAmount\\n ) external view returns (uint256, uint256);\\n\\n function checkMembership(address account, VToken vToken) external view returns (bool);\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n function exitMarket(address vToken) external returns (uint256);\\n\\n function _supportMarket(VToken vToken) external returns (uint256);\\n\\n function getAssetsIn(address account) external view returns (VToken[] memory);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function updateDelegate(address delegate, bool allowBorrows) external;\\n\\n function unlistMarket(address market) external returns (uint256);\\n}\\n\",\"keccak256\":\"0xc7745d78ac18b3bea5895d9c3fbf609d541fe0377e475c0f0f41d3527486fce4\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport { VTokenInterface } from \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function mintVAI(uint256 mintVAIAmount) external returns (uint256);\\n\\n function repayVAI(uint256 amount) external returns (uint256, uint256);\\n\\n function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256);\\n\\n function liquidateVAI(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint256, uint256);\\n\\n function getMintableVAI(address minter) external view returns (uint256, uint256);\\n\\n function getVAIAddress() external view returns (address);\\n\\n function getVAIRepayAmount(address account) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x1f020ff46cb0efa0ebf563f449fd4d8aa1c8b8ed53c46860d71a08548d7fdfaa\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK,\\n UNLIST_MARKET_NOT_LISTED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0x4f5a41ef380336395706659e2b8f315870dcf3d617ea6f81104424500b15b1ef\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506123ae806100206000396000f3fe608060405234801561001057600080fd5b506004361061035c5760003560e01c806394b2294b116101d3578063c5b4db5511610104578063e37d4b79116100a2578063ede4edd01161007c578063ede4edd01461096a578063f445d70314610990578063f851a440146109be578063fa6331d8146109c65761035c565b8063e37d4b791461090d578063e85a296014610933578063e8755446146109625761035c565b8063d3270f99116100de578063d3270f99146108a1578063dce15449146108a9578063dcfbc0c7146108d5578063ddbf54fd146108dd5761035c565b8063c5b4db551461086d578063c5f956af14610891578063c7ee005e146108995761035c565b8063b8324c7c11610171578063bec04f721161014b578063bec04f72146107b7578063bf32442d146107bf578063c2998238146107c7578063c488847b146108375761035c565b8063b8324c7c1461073b578063bb82aa5e14610789578063bbb8864a146107915761035c565b8063a78dc775116101ad578063a78dc77514610670578063abfceffc146106b5578063b0772d0b1461072b578063b2eafc39146107335761035c565b806394b2294b1461063a5780639bb27d6214610642578063a76b3fda1461064a5761035c565b8063425fad58116102ad5780637d172bd51161024b5780638c1ac18a116102255780638c1ac18a146105965780638e8f294b146105bc5780639254f5e514610604578063929fe9a11461060c5761035c565b80637d172bd5146105605780637dc0d1d0146105685780638a7dc165146105705761035c565b806352d84d1e1161028757806352d84d1e1461050d5780635dd3fc9d1461052a578063719f701b1461055057806376551383146105585761035c565b8063425fad58146104d75780634a584432146104df5780634ada90af146105055761035c565b806310b983381161031a57806326782247116102f457806326782247146104735780632bc7e29e1461047b5780634088c73e146104a157806341a18d2c146104a95761035c565b806310b983381461041957806321af45691461044757806324a3d6221461046b5761035c565b80627e3dd21461036157806302c3bcbb1461037d57806304ef9d58146103b55780630686dab6146103bd57806308e0225c146103e35780630db4b4e514610411575b600080fd5b6103696109ce565b604080519115158252519081900360200190f35b6103a36004803603602081101561039357600080fd5b50356001600160a01b03166109d4565b60408051918252519081900360200190f35b6103a36109e6565b6103a3600480360360208110156103d357600080fd5b50356001600160a01b03166109ec565b6103a3600480360360408110156103f957600080fd5b506001600160a01b0381358116916020013516610ee0565b6103a3610efd565b6103696004803603604081101561042f57600080fd5b506001600160a01b0381358116916020013516610f03565b61044f610f23565b604080516001600160a01b039092168252519081900360200190f35b61044f610f32565b61044f610f41565b6103a36004803603602081101561049157600080fd5b50356001600160a01b0316610f50565b610369610f62565b6103a3600480360360408110156104bf57600080fd5b506001600160a01b0381358116916020013516610f6b565b610369610f88565b6103a3600480360360208110156104f557600080fd5b50356001600160a01b0316610f97565b6103a3610fa9565b61044f6004803603602081101561052357600080fd5b5035610faf565b6103a36004803603602081101561054057600080fd5b50356001600160a01b0316610fd6565b6103a3610fe8565b610369610fee565b61044f610ffc565b61044f61100b565b6103a36004803603602081101561058657600080fd5b50356001600160a01b031661101a565b610369600480360360208110156105ac57600080fd5b50356001600160a01b031661102c565b6105e2600480360360208110156105d257600080fd5b50356001600160a01b0316611041565b6040805193151584526020840192909252151582820152519081900360600190f35b61044f611067565b6103696004803603604081101561062257600080fd5b506001600160a01b0381358116916020013516611076565b6103a36110aa565b61044f6110b0565b6103a36004803603602081101561066057600080fd5b50356001600160a01b03166110bf565b61069c6004803603604081101561068657600080fd5b506001600160a01b03813516906020013561121d565b6040805192835260208301919091528051918290030190f35b6106db600480360360208110156106cb57600080fd5b50356001600160a01b03166112bc565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156107175781810151838201526020016106ff565b505050509050019250505060405180910390f35b6106db611444565b61044f6114a6565b6107616004803603602081101561075157600080fd5b50356001600160a01b03166114b5565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61044f6114df565b6103a3600480360360208110156107a757600080fd5b50356001600160a01b03166114ee565b6103a3611500565b61044f611506565b6106db600480360360208110156107dd57600080fd5b8101906020810181356401000000008111156107f857600080fd5b82018360208201111561080a57600080fd5b8035906020019184602083028401116401000000008311171561082c57600080fd5b509092509050611515565b61069c6004803603606081101561084d57600080fd5b506001600160a01b038135811691602081013590911690604001356115ab565b610875611653565b604080516001600160e01b039092168252519081900360200190f35b61044f611666565b61044f611675565b61044f611684565b61044f600480360360408110156108bf57600080fd5b506001600160a01b038135169060200135611693565b61044f6116c8565b61090b600480360360408110156108f357600080fd5b506001600160a01b03813516906020013515156116d7565b005b6107616004803603602081101561092357600080fd5b50356001600160a01b031661176e565b6103696004803603604081101561094957600080fd5b5080356001600160a01b0316906020013560ff16611798565b6103a36117d8565b6103a36004803603602081101561098057600080fd5b50356001600160a01b03166117de565b610369600480360360408110156109a657600080fd5b506001600160a01b0381358116916020013516611a88565b61044f611aa8565b6103a3611ab7565b60015b90565b60276020526000908152604090205481565b60225481565b6000610a2460405180604001604052806015815260200174756e6c6973744d61726b657428616464726573732960581b815250611abd565b6001600160a01b0382166000908152600960205260409020805460ff16610a5957610a5160096018611be1565b915050610edb565b610a64836002611798565b610ab5576040805162461bcd60e51b815260206004820152601b60248201527f626f72726f7720616374696f6e206973206e6f74207061757365640000000000604482015290519081900360640190fd5b610ac0836000611798565b610b11576040805162461bcd60e51b815260206004820152601960248201527f6d696e7420616374696f6e206973206e6f742070617573656400000000000000604482015290519081900360640190fd5b610b1c836001611798565b610b6d576040805162461bcd60e51b815260206004820152601b60248201527f72656465656d20616374696f6e206973206e6f74207061757365640000000000604482015290519081900360640190fd5b610b78836003611798565b610bc9576040805162461bcd60e51b815260206004820152601a60248201527f726570617920616374696f6e206973206e6f7420706175736564000000000000604482015290519081900360640190fd5b610bd4836007611798565b610c0f5760405162461bcd60e51b81526004018080602001828103825260218152602001806123596021913960400191505060405180910390fd5b610c1a836005611798565b610c6b576040805162461bcd60e51b815260206004820152601e60248201527f6c697175696461746520616374696f6e206973206e6f74207061757365640000604482015290519081900360640190fd5b610c76836004611798565b610cc7576040805162461bcd60e51b815260206004820152601a60248201527f7365697a6520616374696f6e206973206e6f7420706175736564000000000000604482015290519081900360640190fd5b610cd2836006611798565b610d23576040805162461bcd60e51b815260206004820152601d60248201527f7472616e7366657220616374696f6e206973206e6f7420706175736564000000604482015290519081900360640190fd5b610d2e836008611798565b610d7f576040805162461bcd60e51b815260206004820181905260248201527f65786974206d61726b657420616374696f6e206973206e6f7420706175736564604482015290519081900360640190fd5b6001600160a01b0383166000908152601f602052604090205415610de0576040805162461bcd60e51b81526020600482015260136024820152720626f72726f7720636170206973206e6f74203606c1b604482015290519081900360640190fd5b6001600160a01b03831660009081526027602052604090205415610e41576040805162461bcd60e51b81526020600482015260136024820152720737570706c7920636170206973206e6f74203606c1b604482015290519081900360640190fd5b600181015415610e98576040805162461bcd60e51b815260206004820152601a60248201527f636f6c6c61746572616c20666163746f72206973206e6f742030000000000000604482015290519081900360640190fd5b805460ff191681556040516001600160a01b038416907f302feb03efd5741df80efe7f97f5d93d74d46a542a3d312d0faae64fa1f3e0e990600090a260005b9150505b919050565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b600d8181548110610fbc57fe5b6000918252602090912001546001600160a01b0316905081565b602b6020526000908152604090205481565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff165b92915050565b60075481565b6025546001600160a01b031681565b60006110ff6040518060400160405280601781526020017f5f737570706f72744d61726b6574286164647265737329000000000000000000815250611abd565b6001600160a01b03821660009081526009602052604090205460ff16156111335761112c600a6011611be1565b9050610edb565b816001600160a01b0316633d9ea3a16040518163ffffffff1660e01b815260040160206040518083038186803b15801561116c57600080fd5b505afa158015611180573d6000803e3d6000fd5b505050506040513d602081101561119657600080fd5b50506001600160a01b03821660009081526009602052604081208054600160ff19918216811783556003830180549092169091558101919091556111d983611c4e565b6111e283611d27565b6040516001600160a01b038416907fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90600090a26000610ed7565b602654604080516304f65f8b60e21b81523060048201526001600160a01b038581166024830152604482018590528251600094859485948594909216926313d97e2c926064808201939291829003018186803b15801561127c57600080fd5b505afa158015611290573d6000803e3d6000fd5b505050506040513d60408110156112a657600080fd5b5080516020909101519097909650945050505050565b6001600160a01b0381166000908152600860209081526040808320805482518185028101850190935280835260609493859392919083018282801561132a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161130c575b50505050509050600081519050606081604051908082528060200260200182016040528015611363578160200160208202803883390190505b50905060005b82811015611437576113796122f1565b6009600086848151811061138957fe5b6020908102919091018101516001600160a01b031682528181019290925260409081016000208151606081018352815460ff9081161580158352600184015495830195909552600390920154909116151591810191909152915061142e578482815181106113f357fe5b602002602001015183878151811061140757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508560010195505b50600101611369565b5092835250909392505050565b6060600d80548060200260200160405190810160405280929190818152602001828054801561149c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161147e575b5050505050905090565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b60408051828152602080840282010190915260609082908290828015611545578160200160208202803883390190505b50905060005b828110156115a25761157886868381811061156257fe5b905060200201356001600160a01b031633611de4565b601381111561158357fe5b82828151811061158f57fe5b602090810291909101015260010161154b565b50949350505050565b60265460408051630779996560e11b81523060048201526001600160a01b038681166024830152858116604483015260648201859052825160009485948594859490921692630ef332ca926084808201939291829003018186803b15801561161257600080fd5b505afa158015611626573d6000803e3d6000fd5b505050506040513d604081101561163c57600080fd5b508051602090910151909890975095505050505050565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b6026546001600160a01b031681565b600860205281600052604060002081815481106116ac57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6116e082611ec8565b336000908152602c602090815260408083206001600160a01b038616845290915290205460ff161515811515141561175f576040805162461bcd60e51b815260206004820152601b60248201527f44656c65676174696f6e2073746174757320756e6368616e6765640000000000604482015290519081900360640190fd5b61176a338383611f1b565b5050565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b0382166000908152602960205260408120818360088111156117bd57fe5b815260208101919091526040016000205460ff169392505050565b60055481565b60006117eb826008611f89565b604080516361bfb47160e11b815233600482015290518391600091829182916001600160a01b0386169163c37f68e2916024808301926080929190829003018186803b15801561183a57600080fd5b505afa15801561184e573d6000803e3d6000fd5b505050506040513d608081101561186457600080fd5b5080516020820151604090920151909450909250905082156118cd576040805162461bcd60e51b815260206004820152601960248201527f6765744163636f756e74536e617073686f74206661696c656400000000000000604482015290519081900360640190fd5b80156118ea576118df600c6002611be1565b945050505050610edb565b60006118f7873385611fd8565b905080156119185761190c600e60038361208b565b95505050505050610edb565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff166119575760009650505050505050610edb565b3360009081526002820160209081526040808320805460ff1916905560089091528120805490915b81811015611a3857886001600160a01b031683828154811061199d57fe5b6000918252602090912001546001600160a01b03161415611a30578260018303815481106119c757fe5b9060005260206000200160009054906101000a90046001600160a01b03168382815481106119f157fe5b600091825260209091200180546001600160a01b0319166001600160a01b03929092169190911790558254611a2a846000198301612311565b50611a38565b60010161197f565b818110611a4157fe5b60405133906001600160a01b038b16907fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90600090a360009b9a5050505050505050505050565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b83811015611b26578181015183820152602001611b0e565b50505050905090810190601f168015611b535780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611b7157600080fd5b505afa158015611b85573d6000803e3d6000fd5b505050506040513d6020811015611b9b57600080fd5b5051611bde576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836013811115611c1057fe5b836018811115611c1c57fe5b604080519283526020830191909152600082820152519081900360600190a1826013811115611c4757fe5b9392505050565b600d5460005b81811015611cd357826001600160a01b0316600d8281548110611c7357fe5b6000918252602090912001546001600160a01b03161415611ccb576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b600101611c54565b5050600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b6000611d316120f9565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b0316611d885781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b0316611db75780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b6000611df1836007611f89565b6001600160a01b0383166000908152600960205260409020611e128161213a565b6001600160a01b038316600090815260028201602052604090205460ff1615611e3f5760009150506110a4565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b6001600160a01b038116611bde576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b038381166000818152602c6020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fcb325b7784f78486e42849c7a50b8c5ee008d00cd90e108a58912c0fcb6288b49281900390910190a3505050565b611f938282611798565b1561176a576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260408120611ff99061213a565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff1661203257506000611c47565b6000806120428587866000612184565b9193509091506000905082601381111561205857fe5b146120725781601381111561206957fe5b92505050611c47565b801561207f576004612069565b50600095945050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460138111156120ba57fe5b8460188111156120c657fe5b604080519283526020830191909152818101859052519081900360600190a18360138111156120f157fe5b949350505050565b6000612135612106612252565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b815250612256565b905090565b805460ff16611bde576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b1580156121f757600080fd5b505afa15801561220b573d6000803e3d6000fd5b505050506040513d606081101561222157600080fd5b5080516020820151604090920151909450909250905082601381111561224357fe5b9a919950975095505050505050565b4390565b60008164010000000084106122e95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122ae578181015183820152602001612296565b50505050905090810190601f1680156122db5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b604080516060810182526000808252602082018190529181019190915290565b8154818355818111156123355760008381526020902061233591810190830161233a565b505050565b6109d191905b808211156123545760008155600101612340565b509056fe656e746572206d61726b657420616374696f6e206973206e6f7420706175736564a265627a7a72315820786e558002340aa32adb0cc5ec43fb1f1b66f8437a6cdbac2d0cd7f0d568a32964736f6c63430005100032", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061035c5760003560e01c806394b2294b116101d3578063c5b4db5511610104578063e37d4b79116100a2578063ede4edd01161007c578063ede4edd01461096a578063f445d70314610990578063f851a440146109be578063fa6331d8146109c65761035c565b8063e37d4b791461090d578063e85a296014610933578063e8755446146109625761035c565b8063d3270f99116100de578063d3270f99146108a1578063dce15449146108a9578063dcfbc0c7146108d5578063ddbf54fd146108dd5761035c565b8063c5b4db551461086d578063c5f956af14610891578063c7ee005e146108995761035c565b8063b8324c7c11610171578063bec04f721161014b578063bec04f72146107b7578063bf32442d146107bf578063c2998238146107c7578063c488847b146108375761035c565b8063b8324c7c1461073b578063bb82aa5e14610789578063bbb8864a146107915761035c565b8063a78dc775116101ad578063a78dc77514610670578063abfceffc146106b5578063b0772d0b1461072b578063b2eafc39146107335761035c565b806394b2294b1461063a5780639bb27d6214610642578063a76b3fda1461064a5761035c565b8063425fad58116102ad5780637d172bd51161024b5780638c1ac18a116102255780638c1ac18a146105965780638e8f294b146105bc5780639254f5e514610604578063929fe9a11461060c5761035c565b80637d172bd5146105605780637dc0d1d0146105685780638a7dc165146105705761035c565b806352d84d1e1161028757806352d84d1e1461050d5780635dd3fc9d1461052a578063719f701b1461055057806376551383146105585761035c565b8063425fad58146104d75780634a584432146104df5780634ada90af146105055761035c565b806310b983381161031a57806326782247116102f457806326782247146104735780632bc7e29e1461047b5780634088c73e146104a157806341a18d2c146104a95761035c565b806310b983381461041957806321af45691461044757806324a3d6221461046b5761035c565b80627e3dd21461036157806302c3bcbb1461037d57806304ef9d58146103b55780630686dab6146103bd57806308e0225c146103e35780630db4b4e514610411575b600080fd5b6103696109ce565b604080519115158252519081900360200190f35b6103a36004803603602081101561039357600080fd5b50356001600160a01b03166109d4565b60408051918252519081900360200190f35b6103a36109e6565b6103a3600480360360208110156103d357600080fd5b50356001600160a01b03166109ec565b6103a3600480360360408110156103f957600080fd5b506001600160a01b0381358116916020013516610ee0565b6103a3610efd565b6103696004803603604081101561042f57600080fd5b506001600160a01b0381358116916020013516610f03565b61044f610f23565b604080516001600160a01b039092168252519081900360200190f35b61044f610f32565b61044f610f41565b6103a36004803603602081101561049157600080fd5b50356001600160a01b0316610f50565b610369610f62565b6103a3600480360360408110156104bf57600080fd5b506001600160a01b0381358116916020013516610f6b565b610369610f88565b6103a3600480360360208110156104f557600080fd5b50356001600160a01b0316610f97565b6103a3610fa9565b61044f6004803603602081101561052357600080fd5b5035610faf565b6103a36004803603602081101561054057600080fd5b50356001600160a01b0316610fd6565b6103a3610fe8565b610369610fee565b61044f610ffc565b61044f61100b565b6103a36004803603602081101561058657600080fd5b50356001600160a01b031661101a565b610369600480360360208110156105ac57600080fd5b50356001600160a01b031661102c565b6105e2600480360360208110156105d257600080fd5b50356001600160a01b0316611041565b6040805193151584526020840192909252151582820152519081900360600190f35b61044f611067565b6103696004803603604081101561062257600080fd5b506001600160a01b0381358116916020013516611076565b6103a36110aa565b61044f6110b0565b6103a36004803603602081101561066057600080fd5b50356001600160a01b03166110bf565b61069c6004803603604081101561068657600080fd5b506001600160a01b03813516906020013561121d565b6040805192835260208301919091528051918290030190f35b6106db600480360360208110156106cb57600080fd5b50356001600160a01b03166112bc565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156107175781810151838201526020016106ff565b505050509050019250505060405180910390f35b6106db611444565b61044f6114a6565b6107616004803603602081101561075157600080fd5b50356001600160a01b03166114b5565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b61044f6114df565b6103a3600480360360208110156107a757600080fd5b50356001600160a01b03166114ee565b6103a3611500565b61044f611506565b6106db600480360360208110156107dd57600080fd5b8101906020810181356401000000008111156107f857600080fd5b82018360208201111561080a57600080fd5b8035906020019184602083028401116401000000008311171561082c57600080fd5b509092509050611515565b61069c6004803603606081101561084d57600080fd5b506001600160a01b038135811691602081013590911690604001356115ab565b610875611653565b604080516001600160e01b039092168252519081900360200190f35b61044f611666565b61044f611675565b61044f611684565b61044f600480360360408110156108bf57600080fd5b506001600160a01b038135169060200135611693565b61044f6116c8565b61090b600480360360408110156108f357600080fd5b506001600160a01b03813516906020013515156116d7565b005b6107616004803603602081101561092357600080fd5b50356001600160a01b031661176e565b6103696004803603604081101561094957600080fd5b5080356001600160a01b0316906020013560ff16611798565b6103a36117d8565b6103a36004803603602081101561098057600080fd5b50356001600160a01b03166117de565b610369600480360360408110156109a657600080fd5b506001600160a01b0381358116916020013516611a88565b61044f611aa8565b6103a3611ab7565b60015b90565b60276020526000908152604090205481565b60225481565b6000610a2460405180604001604052806015815260200174756e6c6973744d61726b657428616464726573732960581b815250611abd565b6001600160a01b0382166000908152600960205260409020805460ff16610a5957610a5160096018611be1565b915050610edb565b610a64836002611798565b610ab5576040805162461bcd60e51b815260206004820152601b60248201527f626f72726f7720616374696f6e206973206e6f74207061757365640000000000604482015290519081900360640190fd5b610ac0836000611798565b610b11576040805162461bcd60e51b815260206004820152601960248201527f6d696e7420616374696f6e206973206e6f742070617573656400000000000000604482015290519081900360640190fd5b610b1c836001611798565b610b6d576040805162461bcd60e51b815260206004820152601b60248201527f72656465656d20616374696f6e206973206e6f74207061757365640000000000604482015290519081900360640190fd5b610b78836003611798565b610bc9576040805162461bcd60e51b815260206004820152601a60248201527f726570617920616374696f6e206973206e6f7420706175736564000000000000604482015290519081900360640190fd5b610bd4836007611798565b610c0f5760405162461bcd60e51b81526004018080602001828103825260218152602001806123596021913960400191505060405180910390fd5b610c1a836005611798565b610c6b576040805162461bcd60e51b815260206004820152601e60248201527f6c697175696461746520616374696f6e206973206e6f74207061757365640000604482015290519081900360640190fd5b610c76836004611798565b610cc7576040805162461bcd60e51b815260206004820152601a60248201527f7365697a6520616374696f6e206973206e6f7420706175736564000000000000604482015290519081900360640190fd5b610cd2836006611798565b610d23576040805162461bcd60e51b815260206004820152601d60248201527f7472616e7366657220616374696f6e206973206e6f7420706175736564000000604482015290519081900360640190fd5b610d2e836008611798565b610d7f576040805162461bcd60e51b815260206004820181905260248201527f65786974206d61726b657420616374696f6e206973206e6f7420706175736564604482015290519081900360640190fd5b6001600160a01b0383166000908152601f602052604090205415610de0576040805162461bcd60e51b81526020600482015260136024820152720626f72726f7720636170206973206e6f74203606c1b604482015290519081900360640190fd5b6001600160a01b03831660009081526027602052604090205415610e41576040805162461bcd60e51b81526020600482015260136024820152720737570706c7920636170206973206e6f74203606c1b604482015290519081900360640190fd5b600181015415610e98576040805162461bcd60e51b815260206004820152601a60248201527f636f6c6c61746572616c20666163746f72206973206e6f742030000000000000604482015290519081900360640190fd5b805460ff191681556040516001600160a01b038416907f302feb03efd5741df80efe7f97f5d93d74d46a542a3d312d0faae64fa1f3e0e990600090a260005b9150505b919050565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b600d8181548110610fbc57fe5b6000918252602090912001546001600160a01b0316905081565b602b6020526000908152604090205481565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b6001600160a01b038082166000908152600960209081526040808320938616835260029093019052205460ff165b92915050565b60075481565b6025546001600160a01b031681565b60006110ff6040518060400160405280601781526020017f5f737570706f72744d61726b6574286164647265737329000000000000000000815250611abd565b6001600160a01b03821660009081526009602052604090205460ff16156111335761112c600a6011611be1565b9050610edb565b816001600160a01b0316633d9ea3a16040518163ffffffff1660e01b815260040160206040518083038186803b15801561116c57600080fd5b505afa158015611180573d6000803e3d6000fd5b505050506040513d602081101561119657600080fd5b50506001600160a01b03821660009081526009602052604081208054600160ff19918216811783556003830180549092169091558101919091556111d983611c4e565b6111e283611d27565b6040516001600160a01b038416907fcf583bb0c569eb967f806b11601c4cb93c10310485c67add5f8362c2f212321f90600090a26000610ed7565b602654604080516304f65f8b60e21b81523060048201526001600160a01b038581166024830152604482018590528251600094859485948594909216926313d97e2c926064808201939291829003018186803b15801561127c57600080fd5b505afa158015611290573d6000803e3d6000fd5b505050506040513d60408110156112a657600080fd5b5080516020909101519097909650945050505050565b6001600160a01b0381166000908152600860209081526040808320805482518185028101850190935280835260609493859392919083018282801561132a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161130c575b50505050509050600081519050606081604051908082528060200260200182016040528015611363578160200160208202803883390190505b50905060005b82811015611437576113796122f1565b6009600086848151811061138957fe5b6020908102919091018101516001600160a01b031682528181019290925260409081016000208151606081018352815460ff9081161580158352600184015495830195909552600390920154909116151591810191909152915061142e578482815181106113f357fe5b602002602001015183878151811061140757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508560010195505b50600101611369565b5092835250909392505050565b6060600d80548060200260200160405190810160405280929190818152602001828054801561149c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161147e575b5050505050905090565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b60408051828152602080840282010190915260609082908290828015611545578160200160208202803883390190505b50905060005b828110156115a25761157886868381811061156257fe5b905060200201356001600160a01b031633611de4565b601381111561158357fe5b82828151811061158f57fe5b602090810291909101015260010161154b565b50949350505050565b60265460408051630779996560e11b81523060048201526001600160a01b038681166024830152858116604483015260648201859052825160009485948594859490921692630ef332ca926084808201939291829003018186803b15801561161257600080fd5b505afa158015611626573d6000803e3d6000fd5b505050506040513d604081101561163c57600080fd5b508051602090910151909890975095505050505050565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b6026546001600160a01b031681565b600860205281600052604060002081815481106116ac57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6116e082611ec8565b336000908152602c602090815260408083206001600160a01b038616845290915290205460ff161515811515141561175f576040805162461bcd60e51b815260206004820152601b60248201527f44656c65676174696f6e2073746174757320756e6368616e6765640000000000604482015290519081900360640190fd5b61176a338383611f1b565b5050565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b0382166000908152602960205260408120818360088111156117bd57fe5b815260208101919091526040016000205460ff169392505050565b60055481565b60006117eb826008611f89565b604080516361bfb47160e11b815233600482015290518391600091829182916001600160a01b0386169163c37f68e2916024808301926080929190829003018186803b15801561183a57600080fd5b505afa15801561184e573d6000803e3d6000fd5b505050506040513d608081101561186457600080fd5b5080516020820151604090920151909450909250905082156118cd576040805162461bcd60e51b815260206004820152601960248201527f6765744163636f756e74536e617073686f74206661696c656400000000000000604482015290519081900360640190fd5b80156118ea576118df600c6002611be1565b945050505050610edb565b60006118f7873385611fd8565b905080156119185761190c600e60038361208b565b95505050505050610edb565b6001600160a01b0385166000908152600960209081526040808320338452600281019092529091205460ff166119575760009650505050505050610edb565b3360009081526002820160209081526040808320805460ff1916905560089091528120805490915b81811015611a3857886001600160a01b031683828154811061199d57fe5b6000918252602090912001546001600160a01b03161415611a30578260018303815481106119c757fe5b9060005260206000200160009054906101000a90046001600160a01b03168382815481106119f157fe5b600091825260209091200180546001600160a01b0319166001600160a01b03929092169190911790558254611a2a846000198301612311565b50611a38565b60010161197f565b818110611a4157fe5b60405133906001600160a01b038b16907fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d90600090a360009b9a5050505050505050505050565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b83811015611b26578181015183820152602001611b0e565b50505050905090810190601f168015611b535780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611b7157600080fd5b505afa158015611b85573d6000803e3d6000fd5b505050506040513d6020811015611b9b57600080fd5b5051611bde576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0836013811115611c1057fe5b836018811115611c1c57fe5b604080519283526020830191909152600082820152519081900360600190a1826013811115611c4757fe5b9392505050565b600d5460005b81811015611cd357826001600160a01b0316600d8281548110611c7357fe5b6000918252602090912001546001600160a01b03161415611ccb576040805162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b604482015290519081900360640190fd5b600101611c54565b5050600d80546001810182556000919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0392909216919091179055565b6000611d316120f9565b6001600160a01b03831660009081526010602090815260408083206011909252909120815492935090916001600160e01b0316611d885781546001600160e01b0319166ec097ce7bc90715b34b9f10000000001782555b80546001600160e01b0316611db75780546001600160e01b0319166ec097ce7bc90715b34b9f10000000001781555b805463ffffffff909316600160e01b026001600160e01b0393841681179091558154909216909117905550565b6000611df1836007611f89565b6001600160a01b0383166000908152600960205260409020611e128161213a565b6001600160a01b038316600090815260028201602052604090205460ff1615611e3f5760009150506110a4565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b6001600160a01b038116611bde576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b038381166000818152602c6020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fcb325b7784f78486e42849c7a50b8c5ee008d00cd90e108a58912c0fcb6288b49281900390910190a3505050565b611f938282611798565b1561176a576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260408120611ff99061213a565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff1661203257506000611c47565b6000806120428587866000612184565b9193509091506000905082601381111561205857fe5b146120725781601381111561206957fe5b92505050611c47565b801561207f576004612069565b50600095945050505050565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa08460138111156120ba57fe5b8460188111156120c657fe5b604080519283526020830191909152818101859052519081900360600190a18360138111156120f157fe5b949350505050565b6000612135612106612252565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b815250612256565b905090565b805460ff16611bde576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b1580156121f757600080fd5b505afa15801561220b573d6000803e3d6000fd5b505050506040513d606081101561222157600080fd5b5080516020820151604090920151909450909250905082601381111561224357fe5b9a919950975095505050505050565b4390565b60008164010000000084106122e95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122ae578181015183820152602001612296565b50505050905090810190601f1680156122db5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b604080516060810182526000808252602082018190529181019190915290565b8154818355818111156123355760008381526020902061233591810190830161233a565b505050565b6109d191905b808211156123545760008155600101612340565b509056fe656e746572206d61726b657420616374696f6e206973206e6f7420706175736564a265627a7a72315820786e558002340aa32adb0cc5ec43fb1f1b66f8437a6cdbac2d0cd7f0d568a32964736f6c63430005100032", "devdoc": { "author": "Venus", "details": "This facet contains all the methods related to the market's management in the pool", @@ -1244,6 +1278,13 @@ }, "return": "(errorCode, number of vTokenCollateral tokens to be seized in a liquidation)" }, + "unlistMarket(address)": { + "details": "Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0", + "params": { + "market": "The address of the market (vToken) to unlist" + }, + "return": "uint256 0=success, otherwise a failure. (See enum Error for details)" + }, "updateDelegate(address,bool)": { "params": { "approved": "Whether to grant (true) or revoke (false) the borrowing or redeeming rights", @@ -1288,6 +1329,9 @@ "liquidateVAICalculateSeizeTokens(address,uint256)": { "notice": "Calculate number of tokens of collateral asset to seize given an underlying amount" }, + "unlistMarket(address)": { + "notice": "Unlist a market by setting isListed to false" + }, "updateDelegate(address,bool)": { "notice": "Grants or revokes the borrowing or redeeming delegate rights to / from an account If allowed, the delegate will be able to borrow funds on behalf of the sender Upon a delegated borrow, the delegate will receive the funds, and the borrower will see the debt on their account Upon a delegated redeem, the delegate will receive the redeemed amount and the approver will see a deduction in his vToken balance" } @@ -1297,7 +1341,7 @@ "storageLayout": { "storage": [ { - "astId": 2391, + "astId": 2510, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "admin", "offset": 0, @@ -1305,7 +1349,7 @@ "type": "t_address" }, { - "astId": 2393, + "astId": 2512, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "pendingAdmin", "offset": 0, @@ -1313,7 +1357,7 @@ "type": "t_address" }, { - "astId": 2395, + "astId": 2514, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "comptrollerImplementation", "offset": 0, @@ -1321,7 +1365,7 @@ "type": "t_address" }, { - "astId": 2397, + "astId": 2516, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "pendingComptrollerImplementation", "offset": 0, @@ -1329,15 +1373,15 @@ "type": "t_address" }, { - "astId": 2404, + "astId": 2523, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "oracle", "offset": 0, "slot": "4", - "type": "t_contract(PriceOracle)12051" + "type": "t_contract(PriceOracle)12353" }, { - "astId": 2406, + "astId": 2525, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "closeFactorMantissa", "offset": 0, @@ -1345,7 +1389,7 @@ "type": "t_uint256" }, { - "astId": 2408, + "astId": 2527, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "liquidationIncentiveMantissa", "offset": 0, @@ -1353,7 +1397,7 @@ "type": "t_uint256" }, { - "astId": 2410, + "astId": 2529, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "maxAssets", "offset": 0, @@ -1361,23 +1405,23 @@ "type": "t_uint256" }, { - "astId": 2415, + "astId": 2534, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "accountAssets", "offset": 0, "slot": "8", - "type": "t_mapping(t_address,t_array(t_contract(VToken)22978)dyn_storage)" + "type": "t_mapping(t_address,t_array(t_contract(VToken)23491)dyn_storage)" }, { - "astId": 2430, + "astId": 2549, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "markets", "offset": 0, "slot": "9", - "type": "t_mapping(t_address,t_struct(Market)2426_storage)" + "type": "t_mapping(t_address,t_struct(Market)2545_storage)" }, { - "astId": 2432, + "astId": 2551, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "pauseGuardian", "offset": 0, @@ -1385,7 +1429,7 @@ "type": "t_address" }, { - "astId": 2434, + "astId": 2553, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_mintGuardianPaused", "offset": 20, @@ -1393,7 +1437,7 @@ "type": "t_bool" }, { - "astId": 2436, + "astId": 2555, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_borrowGuardianPaused", "offset": 21, @@ -1401,7 +1445,7 @@ "type": "t_bool" }, { - "astId": 2438, + "astId": 2557, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "transferGuardianPaused", "offset": 22, @@ -1409,7 +1453,7 @@ "type": "t_bool" }, { - "astId": 2440, + "astId": 2559, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "seizeGuardianPaused", "offset": 23, @@ -1417,7 +1461,7 @@ "type": "t_bool" }, { - "astId": 2444, + "astId": 2563, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "mintGuardianPaused", "offset": 0, @@ -1425,7 +1469,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2448, + "astId": 2567, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "borrowGuardianPaused", "offset": 0, @@ -1433,15 +1477,15 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2456, + "astId": 2575, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "allMarkets", "offset": 0, "slot": "13", - "type": "t_array(t_contract(VToken)22978)dyn_storage" + "type": "t_array(t_contract(VToken)23491)dyn_storage" }, { - "astId": 2458, + "astId": 2577, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusRate", "offset": 0, @@ -1449,7 +1493,7 @@ "type": "t_uint256" }, { - "astId": 2462, + "astId": 2581, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusSpeeds", "offset": 0, @@ -1457,23 +1501,23 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2466, + "astId": 2585, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusSupplyState", "offset": 0, "slot": "16", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)" }, { - "astId": 2470, + "astId": 2589, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusBorrowState", "offset": 0, "slot": "17", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)" }, { - "astId": 2476, + "astId": 2595, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusSupplierIndex", "offset": 0, @@ -1481,7 +1525,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2482, + "astId": 2601, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusBorrowerIndex", "offset": 0, @@ -1489,7 +1533,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2486, + "astId": 2605, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusAccrued", "offset": 0, @@ -1497,15 +1541,15 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2488, + "astId": 2607, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "vaiController", "offset": 0, "slot": "21", - "type": "t_contract(VAIControllerInterface)15527" + "type": "t_contract(VAIControllerInterface)15651" }, { - "astId": 2492, + "astId": 2611, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "mintedVAIs", "offset": 0, @@ -1513,7 +1557,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2494, + "astId": 2613, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "vaiMintRate", "offset": 0, @@ -1521,7 +1565,7 @@ "type": "t_uint256" }, { - "astId": 2496, + "astId": 2615, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "mintVAIGuardianPaused", "offset": 0, @@ -1529,7 +1573,7 @@ "type": "t_bool" }, { - "astId": 2498, + "astId": 2617, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "repayVAIGuardianPaused", "offset": 1, @@ -1537,7 +1581,7 @@ "type": "t_bool" }, { - "astId": 2500, + "astId": 2619, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "protocolPaused", "offset": 2, @@ -1545,7 +1589,7 @@ "type": "t_bool" }, { - "astId": 2502, + "astId": 2621, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusVAIRate", "offset": 0, @@ -1553,7 +1597,7 @@ "type": "t_uint256" }, { - "astId": 2507, + "astId": 2626, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusVAIVaultRate", "offset": 0, @@ -1561,7 +1605,7 @@ "type": "t_uint256" }, { - "astId": 2509, + "astId": 2628, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "vaiVaultAddress", "offset": 0, @@ -1569,7 +1613,7 @@ "type": "t_address" }, { - "astId": 2511, + "astId": 2630, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "releaseStartBlock", "offset": 0, @@ -1577,7 +1621,7 @@ "type": "t_uint256" }, { - "astId": 2513, + "astId": 2632, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "minReleaseAmount", "offset": 0, @@ -1585,7 +1629,7 @@ "type": "t_uint256" }, { - "astId": 2518, + "astId": 2637, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "borrowCapGuardian", "offset": 0, @@ -1593,7 +1637,7 @@ "type": "t_address" }, { - "astId": 2522, + "astId": 2641, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "borrowCaps", "offset": 0, @@ -1601,7 +1645,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2527, + "astId": 2646, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "treasuryGuardian", "offset": 0, @@ -1609,7 +1653,7 @@ "type": "t_address" }, { - "astId": 2529, + "astId": 2648, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "treasuryAddress", "offset": 0, @@ -1617,7 +1661,7 @@ "type": "t_address" }, { - "astId": 2531, + "astId": 2650, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "treasuryPercent", "offset": 0, @@ -1625,7 +1669,7 @@ "type": "t_uint256" }, { - "astId": 2538, + "astId": 2657, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusContributorSpeeds", "offset": 0, @@ -1633,7 +1677,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2542, + "astId": 2661, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "lastContributorBlock", "offset": 0, @@ -1641,7 +1685,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2547, + "astId": 2666, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "liquidatorContract", "offset": 0, @@ -1649,15 +1693,15 @@ "type": "t_address" }, { - "astId": 2552, + "astId": 2671, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "comptrollerLens", "offset": 0, "slot": "38", - "type": "t_contract(ComptrollerLensInterface)2366" + "type": "t_contract(ComptrollerLensInterface)2485" }, { - "astId": 2559, + "astId": 2678, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "supplyCaps", "offset": 0, @@ -1665,7 +1709,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2564, + "astId": 2683, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "accessControl", "offset": 0, @@ -1673,7 +1717,7 @@ "type": "t_address" }, { - "astId": 2570, + "astId": 2689, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_actionPaused", "offset": 0, @@ -1681,7 +1725,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" }, { - "astId": 2577, + "astId": 2696, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusBorrowSpeeds", "offset": 0, @@ -1689,7 +1733,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2581, + "astId": 2700, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "venusSupplySpeeds", "offset": 0, @@ -1697,7 +1741,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2590, + "astId": 2709, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "approvedDelegates", "offset": 0, @@ -1705,7 +1749,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2597, + "astId": 2716, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "isForcedLiquidationEnabled", "offset": 0, @@ -1713,23 +1757,23 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2615, + "astId": 2734, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_selectorToFacetAndPosition", "offset": 0, "slot": "46", - "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2605_storage)" + "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2724_storage)" }, { - "astId": 2619, + "astId": 2738, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_facetFunctionSelectors", "offset": 0, "slot": "47", - "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2611_storage)" + "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2730_storage)" }, { - "astId": 2622, + "astId": 2741, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "_facetAddresses", "offset": 0, @@ -1737,15 +1781,15 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 2627, + "astId": 2746, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "prime", "offset": 0, "slot": "49", - "type": "t_contract(IPrime)12228" + "type": "t_contract(IPrime)12530" }, { - "astId": 2636, + "astId": 2755, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "isForcedLiquidationEnabledForUser", "offset": 0, @@ -1753,7 +1797,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2641, + "astId": 2760, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "xvs", "offset": 0, @@ -1761,7 +1805,7 @@ "type": "t_address" }, { - "astId": 2643, + "astId": 2762, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "xvsVToken", "offset": 0, @@ -1787,8 +1831,8 @@ "label": "bytes4[]", "numberOfBytes": "32" }, - "t_array(t_contract(VToken)22978)dyn_storage": { - "base": "t_contract(VToken)22978", + "t_array(t_contract(VToken)23491)dyn_storage": { + "base": "t_contract(VToken)23491", "encoding": "dynamic_array", "label": "contract VToken[]", "numberOfBytes": "32" @@ -1803,37 +1847,37 @@ "label": "bytes4", "numberOfBytes": "4" }, - "t_contract(ComptrollerLensInterface)2366": { + "t_contract(ComptrollerLensInterface)2485": { "encoding": "inplace", "label": "contract ComptrollerLensInterface", "numberOfBytes": "20" }, - "t_contract(IPrime)12228": { + "t_contract(IPrime)12530": { "encoding": "inplace", "label": "contract IPrime", "numberOfBytes": "20" }, - "t_contract(PriceOracle)12051": { + "t_contract(PriceOracle)12353": { "encoding": "inplace", "label": "contract PriceOracle", "numberOfBytes": "20" }, - "t_contract(VAIControllerInterface)15527": { + "t_contract(VAIControllerInterface)15651": { "encoding": "inplace", "label": "contract VAIControllerInterface", "numberOfBytes": "20" }, - "t_contract(VToken)22978": { + "t_contract(VToken)23491": { "encoding": "inplace", "label": "contract VToken", "numberOfBytes": "20" }, - "t_mapping(t_address,t_array(t_contract(VToken)22978)dyn_storage)": { + "t_mapping(t_address,t_array(t_contract(VToken)23491)dyn_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => contract VToken[])", "numberOfBytes": "32", - "value": "t_array(t_contract(VToken)22978)dyn_storage" + "value": "t_array(t_contract(VToken)23491)dyn_storage" }, "t_mapping(t_address,t_bool)": { "encoding": "mapping", @@ -1863,26 +1907,26 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_bool)" }, - "t_mapping(t_address,t_struct(FacetFunctionSelectors)2611_storage)": { + "t_mapping(t_address,t_struct(FacetFunctionSelectors)2730_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV13Storage.FacetFunctionSelectors)", "numberOfBytes": "32", - "value": "t_struct(FacetFunctionSelectors)2611_storage" + "value": "t_struct(FacetFunctionSelectors)2730_storage" }, - "t_mapping(t_address,t_struct(Market)2426_storage)": { + "t_mapping(t_address,t_struct(Market)2545_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.Market)", "numberOfBytes": "32", - "value": "t_struct(Market)2426_storage" + "value": "t_struct(Market)2545_storage" }, - "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)": { + "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.VenusMarketState)", "numberOfBytes": "32", - "value": "t_struct(VenusMarketState)2453_storage" + "value": "t_struct(VenusMarketState)2572_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1891,12 +1935,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2605_storage)": { + "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2724_storage)": { "encoding": "mapping", "key": "t_bytes4", "label": "mapping(bytes4 => struct ComptrollerV13Storage.FacetAddressAndPosition)", "numberOfBytes": "32", - "value": "t_struct(FacetAddressAndPosition)2605_storage" + "value": "t_struct(FacetAddressAndPosition)2724_storage" }, "t_mapping(t_uint256,t_bool)": { "encoding": "mapping", @@ -1905,12 +1949,12 @@ "numberOfBytes": "32", "value": "t_bool" }, - "t_struct(FacetAddressAndPosition)2605_storage": { + "t_struct(FacetAddressAndPosition)2724_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetAddressAndPosition", "members": [ { - "astId": 2602, + "astId": 2721, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "facetAddress", "offset": 0, @@ -1918,7 +1962,7 @@ "type": "t_address" }, { - "astId": 2604, + "astId": 2723, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "functionSelectorPosition", "offset": 20, @@ -1928,12 +1972,12 @@ ], "numberOfBytes": "32" }, - "t_struct(FacetFunctionSelectors)2611_storage": { + "t_struct(FacetFunctionSelectors)2730_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetFunctionSelectors", "members": [ { - "astId": 2608, + "astId": 2727, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "functionSelectors", "offset": 0, @@ -1941,7 +1985,7 @@ "type": "t_array(t_bytes4)dyn_storage" }, { - "astId": 2610, + "astId": 2729, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "facetAddressPosition", "offset": 0, @@ -1951,12 +1995,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Market)2426_storage": { + "t_struct(Market)2545_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.Market", "members": [ { - "astId": 2417, + "astId": 2536, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "isListed", "offset": 0, @@ -1964,7 +2008,7 @@ "type": "t_bool" }, { - "astId": 2419, + "astId": 2538, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "collateralFactorMantissa", "offset": 0, @@ -1972,7 +2016,7 @@ "type": "t_uint256" }, { - "astId": 2423, + "astId": 2542, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "accountMembership", "offset": 0, @@ -1980,7 +2024,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2425, + "astId": 2544, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "isVenus", "offset": 0, @@ -1990,12 +2034,12 @@ ], "numberOfBytes": "128" }, - "t_struct(VenusMarketState)2453_storage": { + "t_struct(VenusMarketState)2572_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.VenusMarketState", "members": [ { - "astId": 2450, + "astId": 2569, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "index", "offset": 0, @@ -2003,7 +2047,7 @@ "type": "t_uint224" }, { - "astId": 2452, + "astId": 2571, "contract": "contracts/Comptroller/Diamond/facets/MarketFacet.sol:MarketFacet", "label": "block", "offset": 28, diff --git a/deployments/bsctestnet/PolicyFacet.json b/deployments/bsctestnet/PolicyFacet.json index 917899016..f9e289f6d 100644 --- a/deployments/bsctestnet/PolicyFacet.json +++ b/deployments/bsctestnet/PolicyFacet.json @@ -1,5 +1,5 @@ { - "address": "0x7b17b28687B817158c20e3d1bf100106fBE794cf", + "address": "0x085C8d0133291348004AabFfbE7CAc2097aF2aa1", "abi": [ { "anonymous": false, @@ -1545,28 +1545,28 @@ "type": "function" } ], - "transactionHash": "0x5bd746951cb29fab401dc50f4b0ea9e5d7bcb471de29b1cb9be7d4668febe59f", + "transactionHash": "0x181e08abed9857b007a323f03817e74fb6e3e00440d87dbb13a689bfc576bc6d", "receipt": { "to": null, - "from": "0x7Bf1Fe2C42E79dbA813Bf5026B7720935a55ec5f", - "contractAddress": "0x7b17b28687B817158c20e3d1bf100106fBE794cf", - "transactionIndex": 2, - "gasUsed": "3056070", + "from": "0x464779C41C5f1Be598853C1F87bCC7087Ea75f28", + "contractAddress": "0x085C8d0133291348004AabFfbE7CAc2097aF2aa1", + "transactionIndex": 5, + "gasUsed": "3072721", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x87b7a5cc232e9a7869f03c441cd9521541be20dc15663bc16221fb6bac4e2298", - "transactionHash": "0x5bd746951cb29fab401dc50f4b0ea9e5d7bcb471de29b1cb9be7d4668febe59f", + "blockHash": "0x0de3307838eb3adb74cf720401cc02cf8cf4c85a56a51f7b97a4882629674edd", + "transactionHash": "0x181e08abed9857b007a323f03817e74fb6e3e00440d87dbb13a689bfc576bc6d", "logs": [], - "blockNumber": 38507140, - "cumulativeGasUsed": "3171684", + "blockNumber": 40555525, + "cumulativeGasUsed": "4409652", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "506bbeed5e5814c0309e06940945462d", - "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusDelta\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusBorrowIndex\",\"type\":\"uint256\"}],\"name\":\"DistributedBorrowerVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"supplier\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusDelta\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusSupplyIndex\",\"type\":\"uint256\"}],\"name\":\"DistributedSupplierVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"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\":false,\"internalType\":\"uint256\",\"name\":\"newSpeed\",\"type\":\"uint256\"}],\"name\":\"VenusBorrowSpeedUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSpeed\",\"type\":\"uint256\"}],\"name\":\"VenusSupplySpeedUpdated\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"supplySpeeds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"borrowSpeeds\",\"type\":\"uint256[]\"}],\"name\":\"_setVenusSpeeds\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"borrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"borrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenModify\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"getHypotheticalAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateBorrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"liquidateBorrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"mintAmount\",\"type\":\"uint256\"}],\"name\":\"mintAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualMintAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mintTokens\",\"type\":\"uint256\"}],\"name\":\"mintVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"redeemAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"redeemVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"name\":\"repayBorrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowerIndex\",\"type\":\"uint256\"}],\"name\":\"repayBorrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"seizeAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"seizeVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"transferAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"transferVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the hooks used while transferring the assets\",\"methods\":{\"_setVenusSpeeds(address[],uint256[],uint256[])\":{\"details\":\"Allows the contract admin to set XVS speed for a market\",\"params\":{\"borrowSpeeds\":\"New XVS speed for borrow\",\"supplySpeeds\":\"New XVS speed for supply\",\"vTokens\":\"The market whose XVS speed to update\"}},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"borrowAllowed(address,address,uint256)\":{\"params\":{\"borrowAmount\":\"The amount of underlying the account would borrow\",\"borrower\":\"The account which would borrow the asset\",\"vToken\":\"The market to verify the borrow against\"},\"return\":\"0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"borrowVerify(address,address,uint256)\":{\"params\":{\"borrowAmount\":\"The amount of the underlying asset requested to borrow\",\"borrower\":\"The address borrowing the underlying\",\"vToken\":\"Asset whose underlying is being borrowed\"}},\"getAccountLiquidity(address)\":{\"return\":\"(possible error code (semi-opaque), account liquidity in excess of collateral requirements, account shortfall below collateral requirements)\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"params\":{\"account\":\"The account to determine liquidity for\",\"borrowAmount\":\"The amount of underlying to hypothetically borrow\",\"redeemTokens\":\"The number of tokens to hypothetically redeem\",\"vTokenModify\":\"The market to hypothetically redeem/borrow in\"},\"return\":\"(possible error code (semi-opaque), hypothetical account liquidity in excess of collateral requirements, hypothetical account shortfall below collateral requirements)\"},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"liquidateBorrowAllowed(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"repayAmount\":\"The amount of underlying being repaid\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"liquidateBorrowVerify(address,address,address,address,uint256,uint256)\":{\"params\":{\"actualRepayAmount\":\"The amount of underlying being repaid\",\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The amount of collateral token that will be seized\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"mintAllowed(address,address,uint256)\":{\"params\":{\"mintAmount\":\"The amount of underlying being supplied to the market in exchange for tokens\",\"minter\":\"The account which would get the minted tokens\",\"vToken\":\"The market to verify the mint against\"},\"return\":\"0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"mintVerify(address,address,uint256,uint256)\":{\"params\":{\"actualMintAmount\":\"The amount of the underlying asset being minted\",\"mintTokens\":\"The number of tokens being minted\",\"minter\":\"The address minting the tokens\",\"vToken\":\"Asset being minted\"}},\"redeemAllowed(address,address,uint256)\":{\"params\":{\"redeemTokens\":\"The number of vTokens to exchange for the underlying asset in the market\",\"redeemer\":\"The account which would redeem the tokens\",\"vToken\":\"The market to verify the redeem against\"},\"return\":\"0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"redeemVerify(address,address,uint256,uint256)\":{\"params\":{\"redeemAmount\":\"The amount of the underlying asset being redeemed\",\"redeemTokens\":\"The number of tokens being redeemed\",\"redeemer\":\"The address redeeming the tokens\",\"vToken\":\"Asset being redeemed\"}},\"repayBorrowAllowed(address,address,address,uint256)\":{\"params\":{\"borrower\":\"The account which borrowed the asset\",\"payer\":\"The account which would repay the asset\",\"repayAmount\":\"The amount of the underlying asset the account would repay\",\"vToken\":\"The market to verify the repay against\"},\"return\":\"0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"repayBorrowVerify(address,address,address,uint256,uint256)\":{\"params\":{\"actualRepayAmount\":\"The amount of underlying being repaid\",\"borrower\":\"The address of the borrower\",\"payer\":\"The address repaying the borrow\",\"vToken\":\"Asset being repaid\"}},\"seizeAllowed(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The number of collateral tokens to seize\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"seizeVerify(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The number of collateral tokens to seize\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"transferAllowed(address,address,address,uint256)\":{\"params\":{\"dst\":\"The account which receives the tokens\",\"src\":\"The account which sources the tokens\",\"transferTokens\":\"The number of vTokens to transfer\",\"vToken\":\"The market to verify the transfer against\"},\"return\":\"0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"transferVerify(address,address,address,uint256)\":{\"params\":{\"dst\":\"The account which receives the tokens\",\"src\":\"The account which sources the tokens\",\"transferTokens\":\"The number of vTokens to transfer\",\"vToken\":\"Asset being transferred\"}}},\"title\":\"PolicyFacet\"},\"userdoc\":{\"methods\":{\"_setVenusSpeeds(address[],uint256[],uint256[])\":{\"notice\":\"Set XVS speed for a single market\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"borrowAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to borrow the underlying asset of the given market\"},\"borrowVerify(address,address,uint256)\":{\"notice\":\"Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"getAccountLiquidity(address)\":{\"notice\":\"Determine the current account liquidity wrt collateral requirements\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"notice\":\"Determine what the account liquidity would be if the given amounts were redeemed/borrowed\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"liquidateBorrowAllowed(address,address,address,address,uint256)\":{\"notice\":\"Checks if the liquidation should be allowed to occur\"},\"liquidateBorrowVerify(address,address,address,address,uint256,uint256)\":{\"notice\":\"Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"mintAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to mint tokens in the given market\"},\"mintVerify(address,address,uint256,uint256)\":{\"notice\":\"Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"redeemAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to redeem tokens in the given market\"},\"redeemVerify(address,address,uint256,uint256)\":{\"notice\":\"Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"repayBorrowAllowed(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to repay a borrow in the given market\"},\"repayBorrowVerify(address,address,address,uint256,uint256)\":{\"notice\":\"Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"seizeAllowed(address,address,address,address,uint256)\":{\"notice\":\"Checks if the seizing of assets should be allowed to occur\"},\"seizeVerify(address,address,address,address,uint256)\":{\"notice\":\"Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"transferAllowed(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to transfer tokens in the given market\"},\"transferVerify(address,address,address,uint256)\":{\"notice\":\"Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"}},\"notice\":\"This facet contract contains all the external pre-hook functions related to vToken\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/PolicyFacet.sol\":\"PolicyFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0xab3aca949ad85c46d8b7866330594282136109adbdab301d447108a8551e3dc3\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which corresponds to unlimited borrowing.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x13aa5a019c0ea5149d00480b5a3e1281ec316f8d159c52705f45b4c75a5abcb8\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/PolicyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IPolicyFacet } from \\\"../interfaces/IPolicyFacet.sol\\\";\\n\\nimport { XVSRewardsHelper } from \\\"./XVSRewardsHelper.sol\\\";\\n\\n/**\\n * @title PolicyFacet\\n * @author Venus\\n * @dev This facet contains all the hooks used while transferring the assets\\n * @notice This facet contract contains all the external pre-hook functions related to vToken\\n */\\ncontract PolicyFacet is IPolicyFacet, XVSRewardsHelper {\\n /// @notice Emitted when a new borrow-side XVS speed is calculated for a market\\n event VenusBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new supply-side XVS speed is calculated for a market\\n event VenusSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /**\\n * @notice Checks if the account should be allowed to mint tokens in the given market\\n * @param vToken The market to verify the mint against\\n * @param minter The account which would get the minted tokens\\n * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens\\n * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.MINT);\\n ensureListed(markets[vToken]);\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n require(supplyCap != 0, \\\"market supply cap is 0\\\");\\n\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n require(nextTotalSupply <= supplyCap, \\\"market supply cap reached\\\");\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, minter);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being minted\\n * @param minter The address minting the tokens\\n * @param actualMintAmount The amount of the underlying asset being minted\\n * @param mintTokens The number of tokens being minted\\n */\\n // solhint-disable-next-line no-unused-vars\\n function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(minter, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to redeem tokens in the given market\\n * @param vToken The market to verify the redeem against\\n * @param redeemer The account which would redeem the tokens\\n * @param redeemTokens The number of vTokens to exchange for the underlying asset in the market\\n * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256) {\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.REDEEM);\\n\\n uint256 allowed = redeemAllowedInternal(vToken, redeemer, redeemTokens);\\n if (allowed != uint256(Error.NO_ERROR)) {\\n return allowed;\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, redeemer);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being redeemed\\n * @param redeemer The address redeeming the tokens\\n * @param redeemAmount The amount of the underlying asset being redeemed\\n * @param redeemTokens The number of tokens being redeemed\\n */\\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {\\n require(redeemTokens != 0 || redeemAmount == 0, \\\"redeemTokens zero\\\");\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(redeemer, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to borrow the underlying asset of the given market\\n * @param vToken The market to verify the borrow against\\n * @param borrower The account which would borrow the asset\\n * @param borrowAmount The amount of underlying the account would borrow\\n * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.BORROW);\\n\\n ensureListed(markets[vToken]);\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n require(msg.sender == vToken, \\\"sender must be vToken\\\");\\n\\n // attempt to add borrower to the market\\n Error err = addToMarketInternal(VToken(vToken), borrower);\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n }\\n\\n if (oracle.getUnderlyingPrice(VToken(vToken)) == 0) {\\n return uint256(Error.PRICE_ERROR);\\n }\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n // Borrow cap of 0 corresponds to unlimited borrowing\\n if (borrowCap != 0) {\\n uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount);\\n require(nextTotalBorrows < borrowCap, \\\"market borrow cap reached\\\");\\n }\\n\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n\\n // Keep the flywheel moving\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n updateVenusBorrowIndex(vToken, borrowIndex);\\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset whose underlying is being borrowed\\n * @param borrower The address borrowing the underlying\\n * @param borrowAmount The amount of the underlying asset requested to borrow\\n */\\n // solhint-disable-next-line no-unused-vars\\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to repay a borrow in the given market\\n * @param vToken The market to verify the repay against\\n * @param payer The account which would repay the asset\\n * @param borrower The account which borrowed the asset\\n * @param repayAmount The amount of the underlying asset the account would repay\\n * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function repayBorrowAllowed(\\n address vToken,\\n address payer, // solhint-disable-line no-unused-vars\\n address borrower,\\n uint256 repayAmount // solhint-disable-line no-unused-vars\\n ) external returns (uint256) {\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.REPAY);\\n ensureListed(markets[vToken]);\\n\\n // Keep the flywheel moving\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n updateVenusBorrowIndex(vToken, borrowIndex);\\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being repaid\\n * @param payer The address repaying the borrow\\n * @param borrower The address of the borrower\\n * @param actualRepayAmount The amount of underlying being repaid\\n */\\n function repayBorrowVerify(\\n address vToken,\\n address payer, // solhint-disable-line no-unused-vars\\n address borrower,\\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n uint256 borrowerIndex // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the liquidation should be allowed to occur\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n */\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount\\n ) external view returns (uint256) {\\n checkProtocolPauseState();\\n\\n // if we want to pause liquidating to vTokenCollateral, we should pause seizing\\n checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n if (liquidatorContract != address(0) && liquidator != liquidatorContract) {\\n return uint256(Error.UNAUTHORIZED);\\n }\\n\\n ensureListed(markets[vTokenCollateral]);\\n\\n uint256 borrowBalance;\\n if (address(vTokenBorrowed) != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n } else {\\n borrowBalance = vaiController.getVAIRepayAmount(borrower);\\n }\\n\\n if (isForcedLiquidationEnabled[vTokenBorrowed] || isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed]) {\\n if (repayAmount > borrowBalance) {\\n return uint(Error.TOO_MUCH_REPAY);\\n }\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* The borrower must have shortfall in order to be liquidatable */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(borrower, VToken(address(0)), 0, 0);\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall == 0) {\\n return uint256(Error.INSUFFICIENT_SHORTFALL);\\n }\\n\\n // The liquidator may not repay more than what is allowed by the closeFactor\\n //-- maxClose = multipy of closeFactorMantissa and borrowBalance\\n if (repayAmount > mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance)) {\\n return uint256(Error.TOO_MUCH_REPAY);\\n }\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param actualRepayAmount The amount of underlying being repaid\\n * @param seizeTokens The amount of collateral token that will be seized\\n */\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral, // solhint-disable-line no-unused-vars\\n address liquidator,\\n address borrower,\\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vTokenBorrowed);\\n prime.accrueInterestAndUpdateScore(liquidator, vTokenBorrowed);\\n }\\n }\\n\\n /**\\n * @notice Checks if the seizing of assets should be allowed to occur\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param seizeTokens The number of collateral tokens to seize\\n */\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n // We've added VAIController as a borrowed token list check for seize\\n ensureListed(market);\\n\\n if (!market.accountMembership[borrower]) {\\n return uint256(Error.MARKET_NOT_COLLATERAL);\\n }\\n\\n if (address(vTokenBorrowed) != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n\\n if (VToken(vTokenCollateral).comptroller() != VToken(vTokenBorrowed).comptroller()) {\\n return uint256(Error.COMPTROLLER_MISMATCH);\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vTokenCollateral);\\n distributeSupplierVenus(vTokenCollateral, borrower);\\n distributeSupplierVenus(vTokenCollateral, liquidator);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param seizeTokens The number of collateral tokens to seize\\n */\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed, // solhint-disable-line no-unused-vars\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vTokenCollateral);\\n prime.accrueInterestAndUpdateScore(liquidator, vTokenCollateral);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to transfer tokens in the given market\\n * @param vToken The market to verify the transfer against\\n * @param src The account which sources the tokens\\n * @param dst The account which receives the tokens\\n * @param transferTokens The number of vTokens to transfer\\n * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function transferAllowed(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.TRANSFER);\\n\\n // Currently the only consideration is whether or not\\n // the src is allowed to redeem this many tokens\\n uint256 allowed = redeemAllowedInternal(vToken, src, transferTokens);\\n if (allowed != uint256(Error.NO_ERROR)) {\\n return allowed;\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, src);\\n distributeSupplierVenus(vToken, dst);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being transferred\\n * @param src The account which sources the tokens\\n * @param dst The account which receives the tokens\\n * @param transferTokens The number of vTokens to transfer\\n */\\n // solhint-disable-next-line no-unused-vars\\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(src, vToken);\\n prime.accrueInterestAndUpdateScore(dst, vToken);\\n }\\n }\\n\\n /**\\n * @notice Determine the current account liquidity wrt collateral requirements\\n * @return (possible error code (semi-opaque),\\n account liquidity in excess of collateral requirements,\\n * account shortfall below collateral requirements)\\n */\\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256) {\\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n account,\\n VToken(address(0)),\\n 0,\\n 0\\n );\\n\\n return (uint256(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @return (possible error code (semi-opaque),\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) external view returns (uint256, uint256, uint256) {\\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount\\n );\\n return (uint256(err), liquidity, shortfall);\\n }\\n\\n // setter functionality\\n /**\\n * @notice Set XVS speed for a single market\\n * @dev Allows the contract admin to set XVS speed for a market\\n * @param vTokens The market whose XVS speed to update\\n * @param supplySpeeds New XVS speed for supply\\n * @param borrowSpeeds New XVS speed for borrow\\n */\\n function _setVenusSpeeds(\\n VToken[] calldata vTokens,\\n uint256[] calldata supplySpeeds,\\n uint256[] calldata borrowSpeeds\\n ) external {\\n ensureAdmin();\\n\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n ensureNonzeroAddress(address(vTokens[i]));\\n setVenusSpeedInternal(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n function setVenusSpeedInternal(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal {\\n ensureListed(markets[address(vToken)]);\\n\\n if (venusSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. XVS accrued properly for the old speed, and\\n // 2. XVS accrued at the new speed starts after this block.\\n\\n updateVenusSupplyIndex(address(vToken));\\n // Update speed and emit event\\n venusSupplySpeeds[address(vToken)] = supplySpeed;\\n emit VenusSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (venusBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. XVS accrued properly for the old speed, and\\n // 2. XVS accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n updateVenusBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n venusBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit VenusBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe0fb54a32a16f86bd8fe652d699a37f4e8198dd09af0a6306abfc5079e7ba7d5\"},\"contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\n\\n/**\\n * @title XVSRewardsHelper\\n * @author Venus\\n * @dev This contract contains internal functions used in RewardFacet and PolicyFacet\\n * @notice This facet contract contains the shared functions used by the RewardFacet and PolicyFacet\\n */\\ncontract XVSRewardsHelper is FacetBase {\\n /// @notice Emitted when XVS is distributed to a borrower\\n event DistributedBorrowerVenus(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 venusDelta,\\n uint256 venusBorrowIndex\\n );\\n\\n /// @notice Emitted when XVS is distributed to a supplier\\n event DistributedSupplierVenus(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 venusDelta,\\n uint256 venusSupplyIndex\\n );\\n\\n /**\\n * @notice Accrue XVS to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n */\\n function updateVenusBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n VenusMarketState storage borrowState = venusBorrowState[vToken];\\n uint256 borrowSpeed = venusBorrowSpeeds[vToken];\\n uint32 blockNumber = getBlockNumberAsUint32();\\n uint256 deltaBlocks = sub_(blockNumber, borrowState.block);\\n if (deltaBlocks != 0 && borrowSpeed != 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedVenus = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount != 0 ? fraction(accruedVenus, borrowAmount) : Double({ mantissa: 0 });\\n borrowState.index = safe224(add_(Double({ mantissa: borrowState.index }), ratio).mantissa, \\\"224\\\");\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks != 0) {\\n borrowState.block = blockNumber;\\n }\\n }\\n\\n /**\\n * @notice Accrue XVS to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n */\\n function updateVenusSupplyIndex(address vToken) internal {\\n VenusMarketState storage supplyState = venusSupplyState[vToken];\\n uint256 supplySpeed = venusSupplySpeeds[vToken];\\n uint32 blockNumber = getBlockNumberAsUint32();\\n\\n uint256 deltaBlocks = sub_(blockNumber, supplyState.block);\\n if (deltaBlocks != 0 && supplySpeed != 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedVenus = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens != 0 ? fraction(accruedVenus, supplyTokens) : Double({ mantissa: 0 });\\n supplyState.index = safe224(add_(Double({ mantissa: supplyState.index }), ratio).mantissa, \\\"224\\\");\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks != 0) {\\n supplyState.block = blockNumber;\\n }\\n }\\n\\n /**\\n * @notice Calculate XVS accrued by a supplier and possibly transfer it to them\\n * @param vToken The market in which the supplier is interacting\\n * @param supplier The address of the supplier to distribute XVS to\\n */\\n function distributeSupplierVenus(address vToken, address supplier) internal {\\n if (address(vaiVaultAddress) != address(0)) {\\n releaseToVault();\\n }\\n uint256 supplyIndex = venusSupplyState[vToken].index;\\n uint256 supplierIndex = venusSupplierIndex[vToken][supplier];\\n // Update supplier's index to the current index since we are distributing accrued XVS\\n venusSupplierIndex[vToken][supplier] = supplyIndex;\\n if (supplierIndex == 0 && supplyIndex >= venusInitialIndex) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with XVS accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = venusInitialIndex;\\n }\\n // Calculate change in the cumulative sum of the XVS per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n // Multiply of supplierTokens and supplierDelta\\n uint256 supplierDelta = mul_(VToken(vToken).balanceOf(supplier), deltaIndex);\\n // Addition of supplierAccrued and supplierDelta\\n venusAccrued[supplier] = add_(venusAccrued[supplier], supplierDelta);\\n emit DistributedSupplierVenus(VToken(vToken), supplier, supplierDelta, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate XVS accrued by a borrower and possibly transfer it to them\\n * @dev Borrowers will not begin to accrue until after the first interaction with the protocol\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute XVS to\\n */\\n function distributeBorrowerVenus(address vToken, address borrower, Exp memory marketBorrowIndex) internal {\\n if (address(vaiVaultAddress) != address(0)) {\\n releaseToVault();\\n }\\n uint256 borrowIndex = venusBorrowState[vToken].index;\\n uint256 borrowerIndex = venusBorrowerIndex[vToken][borrower];\\n // Update borrowers's index to the current index since we are distributing accrued XVS\\n venusBorrowerIndex[vToken][borrower] = borrowIndex;\\n if (borrowerIndex == 0 && borrowIndex >= venusInitialIndex) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with XVS accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = venusInitialIndex;\\n }\\n // Calculate change in the cumulative sum of the XVS per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n uint256 borrowerDelta = mul_(div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex);\\n venusAccrued[borrower] = add_(venusAccrued[borrower], borrowerDelta);\\n emit DistributedBorrowerVenus(VToken(vToken), borrower, borrowerDelta, borrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0xf13ee35960223103dfc4a661771ae73998d4d4ff5b27f37bbaa52409bbc6103b\"},\"contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface IPolicyFacet {\\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256);\\n\\n function mintVerify(address vToken, address minter, uint256 mintAmount, uint256 mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256);\\n\\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256);\\n\\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external returns (uint256);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint256 repayAmount,\\n uint256 borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount\\n ) external view returns (uint256);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n uint256 seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external returns (uint256);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external;\\n\\n function transferAllowed(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external returns (uint256);\\n\\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external;\\n\\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);\\n\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) external view returns (uint256, uint256, uint256);\\n\\n function _setVenusSpeeds(\\n VToken[] calldata vTokens,\\n uint256[] calldata supplySpeeds,\\n uint256[] calldata borrowSpeeds\\n ) external;\\n}\\n\",\"keccak256\":\"0xbcbbf088aa79d3fcc6945cfbff35b1f2591a803efa6344da1cbf2575f14713be\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function getVAIAddress() public view returns (address);\\n\\n function getMintableVAI(address minter) public view returns (uint, uint);\\n\\n function mintVAI(address minter, uint mintVAIAmount) external returns (uint);\\n\\n function repayVAI(address repayer, uint repayVAIAmount) external returns (uint);\\n\\n function liquidateVAI(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint, uint);\\n\\n function _initializeVenusVAIState(uint blockNumber) external returns (uint);\\n\\n function updateVenusVAIMintIndex() external returns (uint);\\n\\n function calcDistributeVAIMinterVenus(address vaiMinter) external returns (uint, uint, uint, uint);\\n\\n function getVAIRepayAmount(address account) public view returns (uint);\\n}\\n\",\"keccak256\":\"0x17eb6edb1262c4effcad86f614ff20d00256278485054b11aa5cf011ff6f8a86\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0xc77c4dd91f93f778c5048fa0e68cc0cad2fd4a308add54f0172c507858ce06c8\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061364e806100206000396000f3fe608060405234801561001057600080fd5b50600436106103af5760003560e01c80637d172bd5116101f4578063c5b4db551161011a578063e37d4b79116100ad578063ead1a8a01161007c578063ead1a8a014610b88578063f445d70314610c96578063f851a44014610cc4578063fa6331d814610ccc576103af565b8063e37d4b7914610af5578063e85a296014610b1b578063e875544614610b4a578063eabe7d9114610b52576103af565b8063d3270f99116100e9578063d3270f9914610a83578063da3d454c14610a8b578063dce1544914610ac1578063dcfbc0c714610aed576103af565b8063c5b4db5514610a09578063c5f956af14610a2d578063c7ee005e14610a35578063d02f735114610a3d576103af565b80639bb27d6211610192578063bbb8864a11610161578063bbb8864a14610997578063bdcdc258146109bd578063bec04f72146109f9578063bf32442d14610a01576103af565b80639bb27d6214610931578063b2eafc3914610939578063b8324c7c14610941578063bb82aa5e1461098f576103af565b80638c1ac18a116101ce5780638c1ac18a146108b35780638e8f294b146108d95780639254f5e51461092157806394b2294b14610929576103af565b80637d172bd51461087d5780637dc0d1d0146108855780638a7dc1651461088d576103af565b806347ef3b3b116102d95780635c778605116102775780636a56947e116102465780636a56947e146107eb5780636d35bf9114610827578063719f701b1461086d5780637655138314610875576103af565b80635c778605146107235780635dd3fc9d146107595780635ec88c791461077f5780635fc7e71e146107a5576103af565b80634e79238f116102b35780634e79238f1461063a5780634ef4c3e11461069457806351dff989146106ca57806352d84d1e14610706576103af565b806347ef3b3b146105c05780634a5844321461060c5780634ada90af14610632576103af565b806324008a62116103515780634088c73e116103205780634088c73e1461054657806341a18d2c1461054e57806341c728b91461057c578063425fad58146105b8576103af565b806324008a62146104d457806324a3d6221461051057806326782247146105185780632bc7e29e14610520576103af565b80630db4b4e51161038d5780630db4b4e51461042257806310b983381461042a5780631ededc911461046c57806321af4569146104b0576103af565b806302c3bcbb146103b457806304ef9d58146103ec57806308e0225c146103f4575b600080fd5b6103da600480360360208110156103ca57600080fd5b50356001600160a01b0316610cd4565b60408051918252519081900360200190f35b6103da610ce6565b6103da6004803603604081101561040a57600080fd5b506001600160a01b0381358116916020013516610cec565b6103da610d09565b6104586004803603604081101561044057600080fd5b506001600160a01b0381358116916020013516610d0f565b604080519115158252519081900360200190f35b6104ae600480360360a081101561048257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135610d2f565b005b6104b8610db6565b604080516001600160a01b039092168252519081900360200190f35b6103da600480360360808110156104ea57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610dc5565b6104b8610e9a565b6104b8610ea9565b6103da6004803603602081101561053657600080fd5b50356001600160a01b0316610eb8565b610458610eca565b6103da6004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610ed3565b6104ae6004803603608081101561059257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610ef0565b610458610f76565b6104ae600480360360c08110156105d657600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135610f85565b6103da6004803603602081101561062257600080fd5b50356001600160a01b031661107b565b6103da61108d565b6106766004803603608081101561065057600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611093565b60408051938452602084019290925282820152519081900360600190f35b6103da600480360360608110156106aa57600080fd5b506001600160a01b038135811691602081013590911690604001356110c9565b6104ae600480360360808110156106e057600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112cf565b6104b86004803603602081101561071c57600080fd5b5035611320565b6104ae6004803603606081101561073957600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6103da6004803603602081101561076f57600080fd5b50356001600160a01b03166113cc565b6106766004803603602081101561079557600080fd5b50356001600160a01b03166113de565b6103da600480360360a08110156107bb57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611413565b6104ae6004803603608081101561080157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356116ae565b6104ae600480360360a081101561083d57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611783565b6103da611858565b61045861185e565b6104b861186c565b6104b861187b565b6103da600480360360208110156108a357600080fd5b50356001600160a01b031661188a565b610458600480360360208110156108c957600080fd5b50356001600160a01b031661189c565b6108ff600480360360208110156108ef57600080fd5b50356001600160a01b03166118b1565b6040805193151584526020840192909252151582820152519081900360600190f35b6104b86118d7565b6103da6118e6565b6104b86118ec565b6104b86118fb565b6109676004803603602081101561095757600080fd5b50356001600160a01b031661190a565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104b8611934565b6103da600480360360208110156109ad57600080fd5b50356001600160a01b0316611943565b6103da600480360360808110156109d357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611955565b6103da6119a3565b6104b86119a9565b610a116119b8565b604080516001600160e01b039092168252519081900360200190f35b6104b86119ca565b6104b86119d9565b6103da600480360360a0811015610a5357600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356119e8565b6104b8611b91565b6103da60048036036060811015610aa157600080fd5b506001600160a01b03813581169160208101359091169060400135611ba0565b6104b860048036036040811015610ad757600080fd5b506001600160a01b038135169060200135611ee4565b6104b8611f19565b61096760048036036020811015610b0b57600080fd5b50356001600160a01b0316611f28565b61045860048036036040811015610b3157600080fd5b5080356001600160a01b0316906020013560ff16611f52565b6103da611f94565b6103da60048036036060811015610b6857600080fd5b506001600160a01b03813581169160208101359091169060400135611f9a565b6104ae60048036036060811015610b9e57600080fd5b810190602081018135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460208302840111600160201b83111715610beb57600080fd5b919390929091602081019035600160201b811115610c0857600080fd5b820183602082011115610c1a57600080fd5b803590602001918460208302840111600160201b83111715610c3b57600080fd5b919390929091602081019035600160201b811115610c5857600080fd5b820183602082011115610c6a57600080fd5b803590602001918460208302840111600160201b83111715610c8b57600080fd5b509092509050611fe9565b61045860048036036040811015610cac57600080fd5b506001600160a01b03813581169160200135166120c2565b6104b86120e2565b6103da6120f1565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03868116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050505b5050505050565b601e546001600160a01b031681565b6000610dcf6120f7565b610dda85600361214c565b6001600160a01b0385166000908152600960205260409020610dfb9061219f565b610e036135dc565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4757600080fd5b505afa158015610e5b573d6000803e3d6000fd5b505050506040513d6020811015610e7157600080fd5b505190529050610e8186826121ec565b610e8c8685836123a2565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610f5757600080fd5b505af1158015610f6b573d6000803e3d6000fd5b505050505b50505050565b60185462010000900460ff1681565b6031546001600160a01b03161561107357603154604080516367994e8b60e11b81526001600160a01b03868116600483015289811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0389811660048301528b81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b15801561105a57600080fd5b505af115801561106e573d6000803e3d6000fd5b505050505b505050505050565b601f6020526000908152604090205481565b60065481565b6000806000806000806110a88a8a8a8a612542565b9250925092508260138111156110ba57fe5b9a919950975095505050505050565b60006110d36120f7565b6110de84600061214c565b6001600160a01b03841660009081526009602052604090206110ff9061219f565b6001600160a01b03841660009081526027602052604090205480611163576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420737570706c792063617020697320360541b604482015290519081900360640190fd5b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119e57600080fd5b505afa1580156111b2573d6000803e3d6000fd5b505050506040513d60208110156111c857600080fd5b505190506111d46135dc565b6040518060200160405280886001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561121857600080fd5b505afa15801561122c573d6000803e3d6000fd5b505050506040513d602081101561124257600080fd5b5051905290506000611255828488612601565b9050838111156112ac576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420737570706c7920636170207265616368656400000000000000604482015290519081900360640190fd5b6112b588612629565b6112bf88886127b5565b60009450505050505b9392505050565b801515806112db575081155b610ef0576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d818154811061132d57fe5b6000918252602090912001546001600160a01b0316905081565b6031546001600160a01b0316156113c757603154604080516367994e8b60e11b81526001600160a01b03858116600483015286811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156113ae57600080fd5b505af11580156113c2573d6000803e3d6000fd5b505050505b505050565b602b6020526000908152604090205481565b6000806000806000806113f5876000806000612542565b92509250925082601381111561140757fe5b97919650945092505050565b600061141d6120f7565b61142886600561214c565b6025546001600160a01b03161580159061145057506025546001600160a01b03858116911614155b1561145d575060016116a5565b6001600160a01b038516600090815260096020526040902061147e9061219f565b6015546000906001600160a01b03888116911614611540576001600160a01b03871660009081526009602052604090206114b79061219f565b866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b505190506115bc565b60155460408051633c617c9160e11b81526001600160a01b038781166004830152915191909216916378c2f922916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505190505b6001600160a01b0387166000908152602d602052604090205460ff168061160857506001600160a01b038085166000908152603260209081526040808320938b168352929052205460ff165b1561162757808311156116205760115b9150506116a5565b6000611618565b600080611638866000806000612542565b9193509091506000905082601381111561164e57fe5b146116695781601381111561165f57fe5b93505050506116a5565b8061167557600361165f565b61168f60405180602001604052806005548152508461297d565b85111561169d57601161165f565b600093505050505b95945050505050565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b15801561171557600080fd5b505af1158015611729573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0387811660048301528981166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610f5757600080fd5b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03858116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156117ea57600080fd5b505af11580156117fe573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0388811660048301528a81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610d9657600080fd5b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b60075481565b6025546001600160a01b031681565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b600061195f6120f7565b61196a85600661214c565b600061197786868561299c565b90508015611986579050610e92565b61198f86612629565b61199986866127b5565b610e8c86856127b5565b60175481565b6033546001600160a01b031690565b6a0c097ce7bc90715b34b9f160241b81565b6021546001600160a01b031681565b6031546001600160a01b031681565b60006119f26120f7565b6119fd86600461214c565b6001600160a01b0386166000908152600960205260409020611a1e8161219f565b6001600160a01b038416600090815260028201602052604090205460ff16611a47576013611618565b6015546001600160a01b03878116911614611a7d576001600160a01b0386166000908152600960205260409020611a7d9061219f565b856001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505160408051635fe3b56760e01b815290516001600160a01b03928316928a1691635fe3b567916004808301926020929190829003018186803b158015611b2657600080fd5b505afa158015611b3a573d6000803e3d6000fd5b505050506040513d6020811015611b5057600080fd5b50516001600160a01b031614611b67576002611618565b611b7087612629565b611b7a87856127b5565b611b8487866127b5565b6000979650505050505050565b6026546001600160a01b031681565b6000611baa6120f7565b611bb584600261214c565b6001600160a01b0384166000908152600960205260409020611bd69061219f565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16611c9357336001600160a01b03851614611c5c576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba103132903b2a37b5b2b760591b604482015290519081900360640190fd5b6000611c688585612a4e565b90506000816013811115611c7857fe5b14611c9157806013811115611c8957fe5b9150506112c8565b505b600480546040805163fc57d4df60e01b81526001600160a01b03888116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015611ce457600080fd5b505afa158015611cf8573d6000803e3d6000fd5b505050506040513d6020811015611d0e57600080fd5b5051611d1e57600d5b90506112c8565b6001600160a01b0384166000908152601f60205260409020548015611e05576000611dad866001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015611d7b57600080fd5b505afa158015611d8f573d6000803e3d6000fd5b505050506040513d6020811015611da557600080fd5b505185612b32565b9050818110611e03576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b505b600080611e158688600088612542565b91935090915060009050826013811115611e2b57fe5b14611e4657816013811115611e3c57fe5b93505050506112c8565b8015611e53576004611e3c565b611e5b6135dc565b6040518060200160405280896001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e9f57600080fd5b505afa158015611eb3573d6000803e3d6000fd5b505050506040513d6020811015611ec957600080fd5b505190529050611ed988826121ec565b6112bf8888836123a2565b60086020528160005260406000208181548110611efd57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b038216600090815260296020526040812081836008811115611f7757fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b6000611fa46120f7565b611faf84600161214c565b6000611fbc85858561299c565b90508015611fcb5790506112c8565b611fd485612629565b611fde85856127b5565b600095945050505050565b611ff1612b68565b84838114801561200057508082145b612041576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b81811015610f6b5761207088888381811061205b57fe5b905060200201356001600160a01b0316612bb8565b6120ba88888381811061207f57fe5b905060200201356001600160a01b031687878481811061209b57fe5b905060200201358686858181106120ae57fe5b90506020020135612c0b565b600101612044565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b60185462010000900460ff161561214a576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b565b6121568282611f52565b1561219b576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b5050565b805460ff166121e9576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b50565b6001600160a01b0382166000908152601160209081526040808320602a9092528220549091612219612da0565b835490915060009061223b9063ffffffff80851691600160e01b900416612de1565b9050801580159061224b57508215155b156123775760006122c0876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b15801561228e57600080fd5b505afa1580156122a2573d6000803e3d6000fd5b505050506040513d60208110156122b857600080fd5b505187612e1b565b905060006122ce8386612e39565b90506122d86135dc565b826122f257604051806020016040528060008152506122fc565b6122fc8284612e7b565b604080516020810190915288546001600160e01b03168152909150612345906123259083612eb8565b516040805180820190915260038152620c8c8d60ea1b6020820152612edd565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611073915050565b801561107357835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b601b546001600160a01b0316156123bb576123bb612f77565b6001600160a01b0383811660009081526011602090815260408083205460138352818420948716845293909152902080546001600160e01b0390921690819055908015801561241857506a0c097ce7bc90715b34b9f160241b8210155b1561242e57506a0c097ce7bc90715b34b9f160241b5b6124366135dc565b604051806020016040528061244b8585612de1565b815250905060006124b46124ae886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561228e57600080fd5b8361311f565b6001600160a01b0387166000908152601460205260409020549091506124da9082612b32565b6001600160a01b0380881660008181526014602090815260409182902094909455805185815293840188905280519193928b16927f837bdc11fca9f17ce44167944475225a205279b17e88c791c3b1f66f354668fb929081900390910190a350505050505050565b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b1580156125b557600080fd5b505afa1580156125c9573d6000803e3d6000fd5b505050506040513d60608110156125df57600080fd5b508051602082015160409092015190945090925090508260138111156110ba57fe5b600061260b6135dc565b612615858561314d565b90506116a56126238261316e565b84612b32565b6001600160a01b0381166000908152601060209081526040808320602b9092528220549091612656612da0565b83549091506000906126789063ffffffff80851691600160e01b900416612de1565b9050801580159061268857508215155b1561278b576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156126c857600080fd5b505afa1580156126dc573d6000803e3d6000fd5b505050506040513d60208110156126f257600080fd5b5051905060006127028386612e39565b905061270c6135dc565b826127265760405180602001604052806000815250612730565b6127308284612e7b565b604080516020810190915288546001600160e01b03168152909150612759906123259083612eb8565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550610daf915050565b8015610daf57835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b601b546001600160a01b0316156127ce576127ce612f77565b6001600160a01b0382811660009081526010602090815260408083205460128352818420948616845293909152902080546001600160e01b0390921690819055908015801561282b57506a0c097ce7bc90715b34b9f160241b8210155b1561284157506a0c097ce7bc90715b34b9f160241b5b6128496135dc565b604051806020016040528061285e8585612de1565b815250905060006128f0866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156128be57600080fd5b505afa1580156128d2573d6000803e3d6000fd5b505050506040513d60208110156128e857600080fd5b50518361311f565b6001600160a01b0386166000908152601460205260409020549091506129169082612b32565b6001600160a01b0380871660008181526014602090815260409182902094909455805185815293840188905280519193928a16927ffa9d964d891991c113b49e3db1932abd6c67263d387119707aafdd6c4010a3a9929081900390910190a3505050505050565b60006129876135dc565b612991848461314d565b9050610e928161316e565b6001600160a01b03831660009081526009602052604081206129bd9061219f565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166129f5576000611d17565b600080612a058587866000612542565b91935090915060009050826013811115612a1b57fe5b14612a3557816013811115612a2c57fe5b925050506112c8565b8015612a42576004612a2c565b60009695505050505050565b6000612a5b83600761214c565b6001600160a01b0383166000908152600960205260409020612a7c8161219f565b6001600160a01b038316600090815260028201602052604090205460ff1615612aa9576000915050611f8e565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b60006112c88383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b81525061317d565b6000546001600160a01b0316331461214a576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b6001600160a01b0381166121e9576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612c2c9061219f565b6001600160a01b0383166000908152602b60205260409020548214612ca557612c5483612629565b6001600160a01b0383166000818152602b6020908152604091829020859055815185815291517fa9ff26899e4982e7634afa9f70115dcfb61a17d6e8cdd91aa837671d0ff40ba69281900390910190a25b6001600160a01b0383166000908152602a602052604090205481146113c757612ccc6135dc565b6040518060200160405280856001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d1057600080fd5b505afa158015612d24573d6000803e3d6000fd5b505050506040513d6020811015612d3a57600080fd5b505190529050612d4a84826121ec565b6001600160a01b0384166000818152602a6020908152604091829020859055815185815291517f0c62c1bc89ec4c40dccb4d21543e782c5ba43897c0075d108d8964181ea3c51b9281900390910190a250505050565b6000612ddc612dad6131db565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b8152506131df565b905090565b60006112c88383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250613234565b60006112c8612e3284670de0b6b3a7640000612e39565b835161328e565b60006112c883836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f770000000000000000008152506132c1565b612e836135dc565b6040518060200160405280612eaf612ea9866a0c097ce7bc90715b34b9f160241b612e39565b8561328e565b90529392505050565b612ec06135dc565b6040518060200160405280612eaf85600001518560000151612b32565b600081600160e01b8410612f6f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612f34578181015183820152602001612f1c565b50505050905090810190601f168015612f615780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b601c541580612f8e5750601c54612f8c6131db565b105b15612f985761214a565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b158015612fe857600080fd5b505afa158015612ffc573d6000803e3d6000fd5b505050506040513d602081101561301257600080fd5b505190508061302257505061214a565b6000806130386130306131db565b601c54612de1565b90506000613048601a5483612e39565b90508084106130595780925061305d565b8392505b601d5483101561307157505050505061214a565b6130796131db565b601c55601b5461309c906001600160a01b0387811691168563ffffffff61333716565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d9657600080fd5b60006a0c097ce7bc90715b34b9f160241b61313e848460000151612e39565b8161314557fe5b049392505050565b6131556135dc565b6040518060200160405280612eaf856000015185612e39565b51670de0b6b3a7640000900490565b600083830182858210156131d25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b50949350505050565b4390565b600081600160201b8410612f6f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b600081848411156132865760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b505050900390565b60006112c883836040518060400160405280600e81526020016d646976696465206279207a65726f60901b815250613389565b60008315806132ce575082155b156132db575060006112c8565b838302838582816132e857fe5b041483906131d25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113c79084906133eb565b600081836133d85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b508284816133e257fe5b04949350505050565b6133fd826001600160a01b03166135a3565b61344e576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061348c5780518252601f19909201916020918201910161346d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146134ee576040519150601f19603f3d011682016040523d82523d6000602084013e6134f3565b606091505b50915091508161354a576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610f705780806020019051602081101561356657600080fd5b5051610f705760405162461bcd60e51b815260040180806020018281038252602a8152602001806135f0602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e92575050151592915050565b604051806020016040528060008152509056fe5361666542455032303a204245503230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820be65849e326eca99a68cf93f7d1a9747adfc9360b93172fe125fd93ec3bfdcdf64736f6c63430005100032", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103af5760003560e01c80637d172bd5116101f4578063c5b4db551161011a578063e37d4b79116100ad578063ead1a8a01161007c578063ead1a8a014610b88578063f445d70314610c96578063f851a44014610cc4578063fa6331d814610ccc576103af565b8063e37d4b7914610af5578063e85a296014610b1b578063e875544614610b4a578063eabe7d9114610b52576103af565b8063d3270f99116100e9578063d3270f9914610a83578063da3d454c14610a8b578063dce1544914610ac1578063dcfbc0c714610aed576103af565b8063c5b4db5514610a09578063c5f956af14610a2d578063c7ee005e14610a35578063d02f735114610a3d576103af565b80639bb27d6211610192578063bbb8864a11610161578063bbb8864a14610997578063bdcdc258146109bd578063bec04f72146109f9578063bf32442d14610a01576103af565b80639bb27d6214610931578063b2eafc3914610939578063b8324c7c14610941578063bb82aa5e1461098f576103af565b80638c1ac18a116101ce5780638c1ac18a146108b35780638e8f294b146108d95780639254f5e51461092157806394b2294b14610929576103af565b80637d172bd51461087d5780637dc0d1d0146108855780638a7dc1651461088d576103af565b806347ef3b3b116102d95780635c778605116102775780636a56947e116102465780636a56947e146107eb5780636d35bf9114610827578063719f701b1461086d5780637655138314610875576103af565b80635c778605146107235780635dd3fc9d146107595780635ec88c791461077f5780635fc7e71e146107a5576103af565b80634e79238f116102b35780634e79238f1461063a5780634ef4c3e11461069457806351dff989146106ca57806352d84d1e14610706576103af565b806347ef3b3b146105c05780634a5844321461060c5780634ada90af14610632576103af565b806324008a62116103515780634088c73e116103205780634088c73e1461054657806341a18d2c1461054e57806341c728b91461057c578063425fad58146105b8576103af565b806324008a62146104d457806324a3d6221461051057806326782247146105185780632bc7e29e14610520576103af565b80630db4b4e51161038d5780630db4b4e51461042257806310b983381461042a5780631ededc911461046c57806321af4569146104b0576103af565b806302c3bcbb146103b457806304ef9d58146103ec57806308e0225c146103f4575b600080fd5b6103da600480360360208110156103ca57600080fd5b50356001600160a01b0316610cd4565b60408051918252519081900360200190f35b6103da610ce6565b6103da6004803603604081101561040a57600080fd5b506001600160a01b0381358116916020013516610cec565b6103da610d09565b6104586004803603604081101561044057600080fd5b506001600160a01b0381358116916020013516610d0f565b604080519115158252519081900360200190f35b6104ae600480360360a081101561048257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135610d2f565b005b6104b8610db6565b604080516001600160a01b039092168252519081900360200190f35b6103da600480360360808110156104ea57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610dc5565b6104b8610e9a565b6104b8610ea9565b6103da6004803603602081101561053657600080fd5b50356001600160a01b0316610eb8565b610458610eca565b6103da6004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610ed3565b6104ae6004803603608081101561059257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610ef0565b610458610f76565b6104ae600480360360c08110156105d657600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135610f85565b6103da6004803603602081101561062257600080fd5b50356001600160a01b031661107b565b6103da61108d565b6106766004803603608081101561065057600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611093565b60408051938452602084019290925282820152519081900360600190f35b6103da600480360360608110156106aa57600080fd5b506001600160a01b038135811691602081013590911690604001356110c9565b6104ae600480360360808110156106e057600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112cf565b6104b86004803603602081101561071c57600080fd5b5035611320565b6104ae6004803603606081101561073957600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6103da6004803603602081101561076f57600080fd5b50356001600160a01b03166113cc565b6106766004803603602081101561079557600080fd5b50356001600160a01b03166113de565b6103da600480360360a08110156107bb57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611413565b6104ae6004803603608081101561080157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356116ae565b6104ae600480360360a081101561083d57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611783565b6103da611858565b61045861185e565b6104b861186c565b6104b861187b565b6103da600480360360208110156108a357600080fd5b50356001600160a01b031661188a565b610458600480360360208110156108c957600080fd5b50356001600160a01b031661189c565b6108ff600480360360208110156108ef57600080fd5b50356001600160a01b03166118b1565b6040805193151584526020840192909252151582820152519081900360600190f35b6104b86118d7565b6103da6118e6565b6104b86118ec565b6104b86118fb565b6109676004803603602081101561095757600080fd5b50356001600160a01b031661190a565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104b8611934565b6103da600480360360208110156109ad57600080fd5b50356001600160a01b0316611943565b6103da600480360360808110156109d357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611955565b6103da6119a3565b6104b86119a9565b610a116119b8565b604080516001600160e01b039092168252519081900360200190f35b6104b86119ca565b6104b86119d9565b6103da600480360360a0811015610a5357600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356119e8565b6104b8611b91565b6103da60048036036060811015610aa157600080fd5b506001600160a01b03813581169160208101359091169060400135611ba0565b6104b860048036036040811015610ad757600080fd5b506001600160a01b038135169060200135611ee4565b6104b8611f19565b61096760048036036020811015610b0b57600080fd5b50356001600160a01b0316611f28565b61045860048036036040811015610b3157600080fd5b5080356001600160a01b0316906020013560ff16611f52565b6103da611f94565b6103da60048036036060811015610b6857600080fd5b506001600160a01b03813581169160208101359091169060400135611f9a565b6104ae60048036036060811015610b9e57600080fd5b810190602081018135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460208302840111600160201b83111715610beb57600080fd5b919390929091602081019035600160201b811115610c0857600080fd5b820183602082011115610c1a57600080fd5b803590602001918460208302840111600160201b83111715610c3b57600080fd5b919390929091602081019035600160201b811115610c5857600080fd5b820183602082011115610c6a57600080fd5b803590602001918460208302840111600160201b83111715610c8b57600080fd5b509092509050611fe9565b61045860048036036040811015610cac57600080fd5b506001600160a01b03813581169160200135166120c2565b6104b86120e2565b6103da6120f1565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03868116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050505b5050505050565b601e546001600160a01b031681565b6000610dcf6120f7565b610dda85600361214c565b6001600160a01b0385166000908152600960205260409020610dfb9061219f565b610e036135dc565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4757600080fd5b505afa158015610e5b573d6000803e3d6000fd5b505050506040513d6020811015610e7157600080fd5b505190529050610e8186826121ec565b610e8c8685836123a2565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610f5757600080fd5b505af1158015610f6b573d6000803e3d6000fd5b505050505b50505050565b60185462010000900460ff1681565b6031546001600160a01b03161561107357603154604080516367994e8b60e11b81526001600160a01b03868116600483015289811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0389811660048301528b81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b15801561105a57600080fd5b505af115801561106e573d6000803e3d6000fd5b505050505b505050505050565b601f6020526000908152604090205481565b60065481565b6000806000806000806110a88a8a8a8a612542565b9250925092508260138111156110ba57fe5b9a919950975095505050505050565b60006110d36120f7565b6110de84600061214c565b6001600160a01b03841660009081526009602052604090206110ff9061219f565b6001600160a01b03841660009081526027602052604090205480611163576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420737570706c792063617020697320360541b604482015290519081900360640190fd5b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119e57600080fd5b505afa1580156111b2573d6000803e3d6000fd5b505050506040513d60208110156111c857600080fd5b505190506111d46135dc565b6040518060200160405280886001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561121857600080fd5b505afa15801561122c573d6000803e3d6000fd5b505050506040513d602081101561124257600080fd5b5051905290506000611255828488612601565b9050838111156112ac576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420737570706c7920636170207265616368656400000000000000604482015290519081900360640190fd5b6112b588612629565b6112bf88886127b5565b60009450505050505b9392505050565b801515806112db575081155b610ef0576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d818154811061132d57fe5b6000918252602090912001546001600160a01b0316905081565b6031546001600160a01b0316156113c757603154604080516367994e8b60e11b81526001600160a01b03858116600483015286811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156113ae57600080fd5b505af11580156113c2573d6000803e3d6000fd5b505050505b505050565b602b6020526000908152604090205481565b6000806000806000806113f5876000806000612542565b92509250925082601381111561140757fe5b97919650945092505050565b600061141d6120f7565b61142886600561214c565b6025546001600160a01b03161580159061145057506025546001600160a01b03858116911614155b1561145d575060016116a5565b6001600160a01b038516600090815260096020526040902061147e9061219f565b6015546000906001600160a01b03888116911614611540576001600160a01b03871660009081526009602052604090206114b79061219f565b866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b505190506115bc565b60155460408051633c617c9160e11b81526001600160a01b038781166004830152915191909216916378c2f922916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505190505b6001600160a01b0387166000908152602d602052604090205460ff168061160857506001600160a01b038085166000908152603260209081526040808320938b168352929052205460ff165b1561162757808311156116205760115b9150506116a5565b6000611618565b600080611638866000806000612542565b9193509091506000905082601381111561164e57fe5b146116695781601381111561165f57fe5b93505050506116a5565b8061167557600361165f565b61168f60405180602001604052806005548152508461297d565b85111561169d57601161165f565b600093505050505b95945050505050565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b15801561171557600080fd5b505af1158015611729573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0387811660048301528981166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610f5757600080fd5b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03858116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156117ea57600080fd5b505af11580156117fe573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0388811660048301528a81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610d9657600080fd5b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b60075481565b6025546001600160a01b031681565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b600061195f6120f7565b61196a85600661214c565b600061197786868561299c565b90508015611986579050610e92565b61198f86612629565b61199986866127b5565b610e8c86856127b5565b60175481565b6033546001600160a01b031690565b6a0c097ce7bc90715b34b9f160241b81565b6021546001600160a01b031681565b6031546001600160a01b031681565b60006119f26120f7565b6119fd86600461214c565b6001600160a01b0386166000908152600960205260409020611a1e8161219f565b6001600160a01b038416600090815260028201602052604090205460ff16611a47576013611618565b6015546001600160a01b03878116911614611a7d576001600160a01b0386166000908152600960205260409020611a7d9061219f565b856001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505160408051635fe3b56760e01b815290516001600160a01b03928316928a1691635fe3b567916004808301926020929190829003018186803b158015611b2657600080fd5b505afa158015611b3a573d6000803e3d6000fd5b505050506040513d6020811015611b5057600080fd5b50516001600160a01b031614611b67576002611618565b611b7087612629565b611b7a87856127b5565b611b8487866127b5565b6000979650505050505050565b6026546001600160a01b031681565b6000611baa6120f7565b611bb584600261214c565b6001600160a01b0384166000908152600960205260409020611bd69061219f565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16611c9357336001600160a01b03851614611c5c576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba103132903b2a37b5b2b760591b604482015290519081900360640190fd5b6000611c688585612a4e565b90506000816013811115611c7857fe5b14611c9157806013811115611c8957fe5b9150506112c8565b505b600480546040805163fc57d4df60e01b81526001600160a01b03888116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015611ce457600080fd5b505afa158015611cf8573d6000803e3d6000fd5b505050506040513d6020811015611d0e57600080fd5b5051611d1e57600d5b90506112c8565b6001600160a01b0384166000908152601f60205260409020548015611e05576000611dad866001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015611d7b57600080fd5b505afa158015611d8f573d6000803e3d6000fd5b505050506040513d6020811015611da557600080fd5b505185612b32565b9050818110611e03576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b505b600080611e158688600088612542565b91935090915060009050826013811115611e2b57fe5b14611e4657816013811115611e3c57fe5b93505050506112c8565b8015611e53576004611e3c565b611e5b6135dc565b6040518060200160405280896001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e9f57600080fd5b505afa158015611eb3573d6000803e3d6000fd5b505050506040513d6020811015611ec957600080fd5b505190529050611ed988826121ec565b6112bf8888836123a2565b60086020528160005260406000208181548110611efd57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b038216600090815260296020526040812081836008811115611f7757fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b6000611fa46120f7565b611faf84600161214c565b6000611fbc85858561299c565b90508015611fcb5790506112c8565b611fd485612629565b611fde85856127b5565b600095945050505050565b611ff1612b68565b84838114801561200057508082145b612041576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b81811015610f6b5761207088888381811061205b57fe5b905060200201356001600160a01b0316612bb8565b6120ba88888381811061207f57fe5b905060200201356001600160a01b031687878481811061209b57fe5b905060200201358686858181106120ae57fe5b90506020020135612c0b565b600101612044565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b60185462010000900460ff161561214a576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b565b6121568282611f52565b1561219b576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b5050565b805460ff166121e9576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b50565b6001600160a01b0382166000908152601160209081526040808320602a9092528220549091612219612da0565b835490915060009061223b9063ffffffff80851691600160e01b900416612de1565b9050801580159061224b57508215155b156123775760006122c0876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b15801561228e57600080fd5b505afa1580156122a2573d6000803e3d6000fd5b505050506040513d60208110156122b857600080fd5b505187612e1b565b905060006122ce8386612e39565b90506122d86135dc565b826122f257604051806020016040528060008152506122fc565b6122fc8284612e7b565b604080516020810190915288546001600160e01b03168152909150612345906123259083612eb8565b516040805180820190915260038152620c8c8d60ea1b6020820152612edd565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611073915050565b801561107357835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b601b546001600160a01b0316156123bb576123bb612f77565b6001600160a01b0383811660009081526011602090815260408083205460138352818420948716845293909152902080546001600160e01b0390921690819055908015801561241857506a0c097ce7bc90715b34b9f160241b8210155b1561242e57506a0c097ce7bc90715b34b9f160241b5b6124366135dc565b604051806020016040528061244b8585612de1565b815250905060006124b46124ae886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561228e57600080fd5b8361311f565b6001600160a01b0387166000908152601460205260409020549091506124da9082612b32565b6001600160a01b0380881660008181526014602090815260409182902094909455805185815293840188905280519193928b16927f837bdc11fca9f17ce44167944475225a205279b17e88c791c3b1f66f354668fb929081900390910190a350505050505050565b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b1580156125b557600080fd5b505afa1580156125c9573d6000803e3d6000fd5b505050506040513d60608110156125df57600080fd5b508051602082015160409092015190945090925090508260138111156110ba57fe5b600061260b6135dc565b612615858561314d565b90506116a56126238261316e565b84612b32565b6001600160a01b0381166000908152601060209081526040808320602b9092528220549091612656612da0565b83549091506000906126789063ffffffff80851691600160e01b900416612de1565b9050801580159061268857508215155b1561278b576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156126c857600080fd5b505afa1580156126dc573d6000803e3d6000fd5b505050506040513d60208110156126f257600080fd5b5051905060006127028386612e39565b905061270c6135dc565b826127265760405180602001604052806000815250612730565b6127308284612e7b565b604080516020810190915288546001600160e01b03168152909150612759906123259083612eb8565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550610daf915050565b8015610daf57835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b601b546001600160a01b0316156127ce576127ce612f77565b6001600160a01b0382811660009081526010602090815260408083205460128352818420948616845293909152902080546001600160e01b0390921690819055908015801561282b57506a0c097ce7bc90715b34b9f160241b8210155b1561284157506a0c097ce7bc90715b34b9f160241b5b6128496135dc565b604051806020016040528061285e8585612de1565b815250905060006128f0866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156128be57600080fd5b505afa1580156128d2573d6000803e3d6000fd5b505050506040513d60208110156128e857600080fd5b50518361311f565b6001600160a01b0386166000908152601460205260409020549091506129169082612b32565b6001600160a01b0380871660008181526014602090815260409182902094909455805185815293840188905280519193928a16927ffa9d964d891991c113b49e3db1932abd6c67263d387119707aafdd6c4010a3a9929081900390910190a3505050505050565b60006129876135dc565b612991848461314d565b9050610e928161316e565b6001600160a01b03831660009081526009602052604081206129bd9061219f565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff166129f5576000611d17565b600080612a058587866000612542565b91935090915060009050826013811115612a1b57fe5b14612a3557816013811115612a2c57fe5b925050506112c8565b8015612a42576004612a2c565b60009695505050505050565b6000612a5b83600761214c565b6001600160a01b0383166000908152600960205260409020612a7c8161219f565b6001600160a01b038316600090815260028201602052604090205460ff1615612aa9576000915050611f8e565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b60006112c88383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b81525061317d565b6000546001600160a01b0316331461214a576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b6001600160a01b0381166121e9576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612c2c9061219f565b6001600160a01b0383166000908152602b60205260409020548214612ca557612c5483612629565b6001600160a01b0383166000818152602b6020908152604091829020859055815185815291517fa9ff26899e4982e7634afa9f70115dcfb61a17d6e8cdd91aa837671d0ff40ba69281900390910190a25b6001600160a01b0383166000908152602a602052604090205481146113c757612ccc6135dc565b6040518060200160405280856001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d1057600080fd5b505afa158015612d24573d6000803e3d6000fd5b505050506040513d6020811015612d3a57600080fd5b505190529050612d4a84826121ec565b6001600160a01b0384166000818152602a6020908152604091829020859055815185815291517f0c62c1bc89ec4c40dccb4d21543e782c5ba43897c0075d108d8964181ea3c51b9281900390910190a250505050565b6000612ddc612dad6131db565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b8152506131df565b905090565b60006112c88383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250613234565b60006112c8612e3284670de0b6b3a7640000612e39565b835161328e565b60006112c883836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f770000000000000000008152506132c1565b612e836135dc565b6040518060200160405280612eaf612ea9866a0c097ce7bc90715b34b9f160241b612e39565b8561328e565b90529392505050565b612ec06135dc565b6040518060200160405280612eaf85600001518560000151612b32565b600081600160e01b8410612f6f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612f34578181015183820152602001612f1c565b50505050905090810190601f168015612f615780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b601c541580612f8e5750601c54612f8c6131db565b105b15612f985761214a565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b158015612fe857600080fd5b505afa158015612ffc573d6000803e3d6000fd5b505050506040513d602081101561301257600080fd5b505190508061302257505061214a565b6000806130386130306131db565b601c54612de1565b90506000613048601a5483612e39565b90508084106130595780925061305d565b8392505b601d5483101561307157505050505061214a565b6130796131db565b601c55601b5461309c906001600160a01b0387811691168563ffffffff61333716565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d9657600080fd5b60006a0c097ce7bc90715b34b9f160241b61313e848460000151612e39565b8161314557fe5b049392505050565b6131556135dc565b6040518060200160405280612eaf856000015185612e39565b51670de0b6b3a7640000900490565b600083830182858210156131d25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b50949350505050565b4390565b600081600160201b8410612f6f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b600081848411156132865760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b505050900390565b60006112c883836040518060400160405280600e81526020016d646976696465206279207a65726f60901b815250613389565b60008315806132ce575082155b156132db575060006112c8565b838302838582816132e857fe5b041483906131d25760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113c79084906133eb565b600081836133d85760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f34578181015183820152602001612f1c565b508284816133e257fe5b04949350505050565b6133fd826001600160a01b03166135a3565b61344e576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061348c5780518252601f19909201916020918201910161346d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146134ee576040519150601f19603f3d011682016040523d82523d6000602084013e6134f3565b606091505b50915091508161354a576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610f705780806020019051602081101561356657600080fd5b5051610f705760405162461bcd60e51b815260040180806020018281038252602a8152602001806135f0602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e92575050151592915050565b604051806020016040528060008152509056fe5361666542455032303a204245503230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820be65849e326eca99a68cf93f7d1a9747adfc9360b93172fe125fd93ec3bfdcdf64736f6c63430005100032", + "numDeployments": 3, + "solcInputHash": "7674fc0eb5134fe9ab2419cd8945df4b", + "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusDelta\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusBorrowIndex\",\"type\":\"uint256\"}],\"name\":\"DistributedBorrowerVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"supplier\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusDelta\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"venusSupplyIndex\",\"type\":\"uint256\"}],\"name\":\"DistributedSupplierVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"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\":false,\"internalType\":\"uint256\",\"name\":\"newSpeed\",\"type\":\"uint256\"}],\"name\":\"VenusBorrowSpeedUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSpeed\",\"type\":\"uint256\"}],\"name\":\"VenusSupplySpeedUpdated\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"supplySpeeds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"borrowSpeeds\",\"type\":\"uint256[]\"}],\"name\":\"_setVenusSpeeds\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"borrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"borrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenModify\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowAmount\",\"type\":\"uint256\"}],\"name\":\"getHypotheticalAccountLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"name\":\"liquidateBorrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"liquidateBorrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"mintAmount\",\"type\":\"uint256\"}],\"name\":\"mintAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualMintAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"mintTokens\",\"type\":\"uint256\"}],\"name\":\"mintVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"redeemAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"redeemAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"redeemTokens\",\"type\":\"uint256\"}],\"name\":\"redeemVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"repayAmount\",\"type\":\"uint256\"}],\"name\":\"repayBorrowAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"actualRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"borrowerIndex\",\"type\":\"uint256\"}],\"name\":\"repayBorrowVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"seizeAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenCollateral\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"seizeTokens\",\"type\":\"uint256\"}],\"name\":\"seizeVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"transferAllowed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"transferTokens\",\"type\":\"uint256\"}],\"name\":\"transferVerify\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the hooks used while transferring the assets\",\"methods\":{\"_setVenusSpeeds(address[],uint256[],uint256[])\":{\"details\":\"Allows the contract admin to set XVS speed for a market\",\"params\":{\"borrowSpeeds\":\"New XVS speed for borrow\",\"supplySpeeds\":\"New XVS speed for supply\",\"vTokens\":\"The market whose XVS speed to update\"}},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"borrowAllowed(address,address,uint256)\":{\"params\":{\"borrowAmount\":\"The amount of underlying the account would borrow\",\"borrower\":\"The account which would borrow the asset\",\"vToken\":\"The market to verify the borrow against\"},\"return\":\"0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"borrowVerify(address,address,uint256)\":{\"params\":{\"borrowAmount\":\"The amount of the underlying asset requested to borrow\",\"borrower\":\"The address borrowing the underlying\",\"vToken\":\"Asset whose underlying is being borrowed\"}},\"getAccountLiquidity(address)\":{\"return\":\"(possible error code (semi-opaque), account liquidity in excess of collateral requirements, account shortfall below collateral requirements)\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"params\":{\"account\":\"The account to determine liquidity for\",\"borrowAmount\":\"The amount of underlying to hypothetically borrow\",\"redeemTokens\":\"The number of tokens to hypothetically redeem\",\"vTokenModify\":\"The market to hypothetically redeem/borrow in\"},\"return\":\"(possible error code (semi-opaque), hypothetical account liquidity in excess of collateral requirements, hypothetical account shortfall below collateral requirements)\"},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"liquidateBorrowAllowed(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"repayAmount\":\"The amount of underlying being repaid\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"liquidateBorrowVerify(address,address,address,address,uint256,uint256)\":{\"params\":{\"actualRepayAmount\":\"The amount of underlying being repaid\",\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The amount of collateral token that will be seized\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"mintAllowed(address,address,uint256)\":{\"params\":{\"mintAmount\":\"The amount of underlying being supplied to the market in exchange for tokens\",\"minter\":\"The account which would get the minted tokens\",\"vToken\":\"The market to verify the mint against\"},\"return\":\"0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"mintVerify(address,address,uint256,uint256)\":{\"params\":{\"actualMintAmount\":\"The amount of the underlying asset being minted\",\"mintTokens\":\"The number of tokens being minted\",\"minter\":\"The address minting the tokens\",\"vToken\":\"Asset being minted\"}},\"redeemAllowed(address,address,uint256)\":{\"params\":{\"redeemTokens\":\"The number of vTokens to exchange for the underlying asset in the market\",\"redeemer\":\"The account which would redeem the tokens\",\"vToken\":\"The market to verify the redeem against\"},\"return\":\"0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"redeemVerify(address,address,uint256,uint256)\":{\"params\":{\"redeemAmount\":\"The amount of the underlying asset being redeemed\",\"redeemTokens\":\"The number of tokens being redeemed\",\"redeemer\":\"The address redeeming the tokens\",\"vToken\":\"Asset being redeemed\"}},\"repayBorrowAllowed(address,address,address,uint256)\":{\"params\":{\"borrower\":\"The account which borrowed the asset\",\"payer\":\"The account which would repay the asset\",\"repayAmount\":\"The amount of the underlying asset the account would repay\",\"vToken\":\"The market to verify the repay against\"},\"return\":\"0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"repayBorrowVerify(address,address,address,uint256,uint256)\":{\"params\":{\"actualRepayAmount\":\"The amount of underlying being repaid\",\"borrower\":\"The address of the borrower\",\"payer\":\"The address repaying the borrow\",\"vToken\":\"Asset being repaid\"}},\"seizeAllowed(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The number of collateral tokens to seize\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"seizeVerify(address,address,address,address,uint256)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"liquidator\":\"The address repaying the borrow and seizing the collateral\",\"seizeTokens\":\"The number of collateral tokens to seize\",\"vTokenBorrowed\":\"Asset which was borrowed by the borrower\",\"vTokenCollateral\":\"Asset which was used as collateral and will be seized\"}},\"transferAllowed(address,address,address,uint256)\":{\"params\":{\"dst\":\"The account which receives the tokens\",\"src\":\"The account which sources the tokens\",\"transferTokens\":\"The number of vTokens to transfer\",\"vToken\":\"The market to verify the transfer against\"},\"return\":\"0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\"},\"transferVerify(address,address,address,uint256)\":{\"params\":{\"dst\":\"The account which receives the tokens\",\"src\":\"The account which sources the tokens\",\"transferTokens\":\"The number of vTokens to transfer\",\"vToken\":\"Asset being transferred\"}}},\"title\":\"PolicyFacet\"},\"userdoc\":{\"methods\":{\"_setVenusSpeeds(address[],uint256[],uint256[])\":{\"notice\":\"Set XVS speed for a single market\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"borrowAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to borrow the underlying asset of the given market\"},\"borrowVerify(address,address,uint256)\":{\"notice\":\"Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"getAccountLiquidity(address)\":{\"notice\":\"Determine the current account liquidity wrt collateral requirements\"},\"getHypotheticalAccountLiquidity(address,address,uint256,uint256)\":{\"notice\":\"Determine what the account liquidity would be if the given amounts were redeemed/borrowed\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"liquidateBorrowAllowed(address,address,address,address,uint256)\":{\"notice\":\"Checks if the liquidation should be allowed to occur\"},\"liquidateBorrowVerify(address,address,address,address,uint256,uint256)\":{\"notice\":\"Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"mintAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to mint tokens in the given market\"},\"mintVerify(address,address,uint256,uint256)\":{\"notice\":\"Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"redeemAllowed(address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to redeem tokens in the given market\"},\"redeemVerify(address,address,uint256,uint256)\":{\"notice\":\"Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"repayBorrowAllowed(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to repay a borrow in the given market\"},\"repayBorrowVerify(address,address,address,uint256,uint256)\":{\"notice\":\"Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"seizeAllowed(address,address,address,address,uint256)\":{\"notice\":\"Checks if the seizing of assets should be allowed to occur\"},\"seizeVerify(address,address,address,address,uint256)\":{\"notice\":\"Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"},\"transferAllowed(address,address,address,uint256)\":{\"notice\":\"Checks if the account should be allowed to transfer tokens in the given market\"},\"transferVerify(address,address,address,uint256)\":{\"notice\":\"Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\"}},\"notice\":\"This facet contract contains all the external pre-hook functions related to vToken\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/PolicyFacet.sol\":\"PolicyFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x06608bb502e91c33fda8c0dd88cc79a49a078fab521bc27d10fc3a69c1da55f4\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/PolicyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IPolicyFacet } from \\\"../interfaces/IPolicyFacet.sol\\\";\\n\\nimport { XVSRewardsHelper } from \\\"./XVSRewardsHelper.sol\\\";\\n\\n/**\\n * @title PolicyFacet\\n * @author Venus\\n * @dev This facet contains all the hooks used while transferring the assets\\n * @notice This facet contract contains all the external pre-hook functions related to vToken\\n */\\ncontract PolicyFacet is IPolicyFacet, XVSRewardsHelper {\\n /// @notice Emitted when a new borrow-side XVS speed is calculated for a market\\n event VenusBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /// @notice Emitted when a new supply-side XVS speed is calculated for a market\\n event VenusSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n /**\\n * @notice Checks if the account should be allowed to mint tokens in the given market\\n * @param vToken The market to verify the mint against\\n * @param minter The account which would get the minted tokens\\n * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens\\n * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.MINT);\\n ensureListed(markets[vToken]);\\n\\n uint256 supplyCap = supplyCaps[vToken];\\n require(supplyCap != 0, \\\"market supply cap is 0\\\");\\n\\n uint256 vTokenSupply = VToken(vToken).totalSupply();\\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n require(nextTotalSupply <= supplyCap, \\\"market supply cap reached\\\");\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, minter);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being minted\\n * @param minter The address minting the tokens\\n * @param actualMintAmount The amount of the underlying asset being minted\\n * @param mintTokens The number of tokens being minted\\n */\\n // solhint-disable-next-line no-unused-vars\\n function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(minter, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to redeem tokens in the given market\\n * @param vToken The market to verify the redeem against\\n * @param redeemer The account which would redeem the tokens\\n * @param redeemTokens The number of vTokens to exchange for the underlying asset in the market\\n * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256) {\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.REDEEM);\\n\\n uint256 allowed = redeemAllowedInternal(vToken, redeemer, redeemTokens);\\n if (allowed != uint256(Error.NO_ERROR)) {\\n return allowed;\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, redeemer);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being redeemed\\n * @param redeemer The address redeeming the tokens\\n * @param redeemAmount The amount of the underlying asset being redeemed\\n * @param redeemTokens The number of tokens being redeemed\\n */\\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {\\n require(redeemTokens != 0 || redeemAmount == 0, \\\"redeemTokens zero\\\");\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(redeemer, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to borrow the underlying asset of the given market\\n * @param vToken The market to verify the borrow against\\n * @param borrower The account which would borrow the asset\\n * @param borrowAmount The amount of underlying the account would borrow\\n * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.BORROW);\\n ensureListed(markets[vToken]);\\n\\n uint256 borrowCap = borrowCaps[vToken];\\n require(borrowCap != 0, \\\"market borrow cap is 0\\\");\\n\\n if (!markets[vToken].accountMembership[borrower]) {\\n // only vTokens may call borrowAllowed if borrower not in market\\n require(msg.sender == vToken, \\\"sender must be vToken\\\");\\n\\n // attempt to add borrower to the market\\n Error err = addToMarketInternal(VToken(vToken), borrower);\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n }\\n\\n if (oracle.getUnderlyingPrice(VToken(vToken)) == 0) {\\n return uint256(Error.PRICE_ERROR);\\n }\\n\\n uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount);\\n require(nextTotalBorrows <= borrowCap, \\\"market borrow cap reached\\\");\\n\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n borrower,\\n VToken(vToken),\\n 0,\\n borrowAmount\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n\\n // Keep the flywheel moving\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n updateVenusBorrowIndex(vToken, borrowIndex);\\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset whose underlying is being borrowed\\n * @param borrower The address borrowing the underlying\\n * @param borrowAmount The amount of the underlying asset requested to borrow\\n */\\n // solhint-disable-next-line no-unused-vars\\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to repay a borrow in the given market\\n * @param vToken The market to verify the repay against\\n * @param payer The account which would repay the asset\\n * @param borrower The account which borrowed the asset\\n * @param repayAmount The amount of the underlying asset the account would repay\\n * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function repayBorrowAllowed(\\n address vToken,\\n address payer, // solhint-disable-line no-unused-vars\\n address borrower,\\n uint256 repayAmount // solhint-disable-line no-unused-vars\\n ) external returns (uint256) {\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.REPAY);\\n ensureListed(markets[vToken]);\\n\\n // Keep the flywheel moving\\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n updateVenusBorrowIndex(vToken, borrowIndex);\\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being repaid\\n * @param payer The address repaying the borrow\\n * @param borrower The address of the borrower\\n * @param actualRepayAmount The amount of underlying being repaid\\n */\\n function repayBorrowVerify(\\n address vToken,\\n address payer, // solhint-disable-line no-unused-vars\\n address borrower,\\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n uint256 borrowerIndex // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vToken);\\n }\\n }\\n\\n /**\\n * @notice Checks if the liquidation should be allowed to occur\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param repayAmount The amount of underlying being repaid\\n */\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount\\n ) external view returns (uint256) {\\n checkProtocolPauseState();\\n\\n // if we want to pause liquidating to vTokenCollateral, we should pause seizing\\n checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n if (liquidatorContract != address(0) && liquidator != liquidatorContract) {\\n return uint256(Error.UNAUTHORIZED);\\n }\\n\\n ensureListed(markets[vTokenCollateral]);\\n\\n uint256 borrowBalance;\\n if (address(vTokenBorrowed) != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n } else {\\n borrowBalance = vaiController.getVAIRepayAmount(borrower);\\n }\\n\\n if (isForcedLiquidationEnabled[vTokenBorrowed] || isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed]) {\\n if (repayAmount > borrowBalance) {\\n return uint(Error.TOO_MUCH_REPAY);\\n }\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* The borrower must have shortfall in order to be liquidatable */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(borrower, VToken(address(0)), 0, 0);\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall == 0) {\\n return uint256(Error.INSUFFICIENT_SHORTFALL);\\n }\\n\\n // The liquidator may not repay more than what is allowed by the closeFactor\\n //-- maxClose = multipy of closeFactorMantissa and borrowBalance\\n if (repayAmount > mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance)) {\\n return uint256(Error.TOO_MUCH_REPAY);\\n }\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param actualRepayAmount The amount of underlying being repaid\\n * @param seizeTokens The amount of collateral token that will be seized\\n */\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral, // solhint-disable-line no-unused-vars\\n address liquidator,\\n address borrower,\\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vTokenBorrowed);\\n prime.accrueInterestAndUpdateScore(liquidator, vTokenBorrowed);\\n }\\n }\\n\\n /**\\n * @notice Checks if the seizing of assets should be allowed to occur\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param seizeTokens The number of collateral tokens to seize\\n */\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n Market storage market = markets[vTokenCollateral];\\n\\n // We've added VAIController as a borrowed token list check for seize\\n ensureListed(market);\\n\\n if (!market.accountMembership[borrower]) {\\n return uint256(Error.MARKET_NOT_COLLATERAL);\\n }\\n\\n if (address(vTokenBorrowed) != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n\\n if (VToken(vTokenCollateral).comptroller() != VToken(vTokenBorrowed).comptroller()) {\\n return uint256(Error.COMPTROLLER_MISMATCH);\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vTokenCollateral);\\n distributeSupplierVenus(vTokenCollateral, borrower);\\n distributeSupplierVenus(vTokenCollateral, liquidator);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vTokenCollateral Asset which was used as collateral and will be seized\\n * @param vTokenBorrowed Asset which was borrowed by the borrower\\n * @param liquidator The address repaying the borrow and seizing the collateral\\n * @param borrower The address of the borrower\\n * @param seizeTokens The number of collateral tokens to seize\\n */\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed, // solhint-disable-line no-unused-vars\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens // solhint-disable-line no-unused-vars\\n ) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(borrower, vTokenCollateral);\\n prime.accrueInterestAndUpdateScore(liquidator, vTokenCollateral);\\n }\\n }\\n\\n /**\\n * @notice Checks if the account should be allowed to transfer tokens in the given market\\n * @param vToken The market to verify the transfer against\\n * @param src The account which sources the tokens\\n * @param dst The account which receives the tokens\\n * @param transferTokens The number of vTokens to transfer\\n * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\\n */\\n function transferAllowed(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external returns (uint256) {\\n // Pausing is a very serious situation - we revert to sound the alarms\\n checkProtocolPauseState();\\n checkActionPauseState(vToken, Action.TRANSFER);\\n\\n // Currently the only consideration is whether or not\\n // the src is allowed to redeem this many tokens\\n uint256 allowed = redeemAllowedInternal(vToken, src, transferTokens);\\n if (allowed != uint256(Error.NO_ERROR)) {\\n return allowed;\\n }\\n\\n // Keep the flywheel moving\\n updateVenusSupplyIndex(vToken);\\n distributeSupplierVenus(vToken, src);\\n distributeSupplierVenus(vToken, dst);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n * @param vToken Asset being transferred\\n * @param src The account which sources the tokens\\n * @param dst The account which receives the tokens\\n * @param transferTokens The number of vTokens to transfer\\n */\\n // solhint-disable-next-line no-unused-vars\\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external {\\n if (address(prime) != address(0)) {\\n prime.accrueInterestAndUpdateScore(src, vToken);\\n prime.accrueInterestAndUpdateScore(dst, vToken);\\n }\\n }\\n\\n /**\\n * @notice Determine the current account liquidity wrt collateral requirements\\n * @return (possible error code (semi-opaque),\\n account liquidity in excess of collateral requirements,\\n * account shortfall below collateral requirements)\\n */\\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256) {\\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n account,\\n VToken(address(0)),\\n 0,\\n 0\\n );\\n\\n return (uint256(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @return (possible error code (semi-opaque),\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) external view returns (uint256, uint256, uint256) {\\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n account,\\n VToken(vTokenModify),\\n redeemTokens,\\n borrowAmount\\n );\\n return (uint256(err), liquidity, shortfall);\\n }\\n\\n // setter functionality\\n /**\\n * @notice Set XVS speed for a single market\\n * @dev Allows the contract admin to set XVS speed for a market\\n * @param vTokens The market whose XVS speed to update\\n * @param supplySpeeds New XVS speed for supply\\n * @param borrowSpeeds New XVS speed for borrow\\n */\\n function _setVenusSpeeds(\\n VToken[] calldata vTokens,\\n uint256[] calldata supplySpeeds,\\n uint256[] calldata borrowSpeeds\\n ) external {\\n ensureAdmin();\\n\\n uint256 numTokens = vTokens.length;\\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numTokens; ++i) {\\n ensureNonzeroAddress(address(vTokens[i]));\\n setVenusSpeedInternal(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n }\\n }\\n\\n function setVenusSpeedInternal(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal {\\n ensureListed(markets[address(vToken)]);\\n\\n if (venusSupplySpeeds[address(vToken)] != supplySpeed) {\\n // Supply speed updated so let's update supply state to ensure that\\n // 1. XVS accrued properly for the old speed, and\\n // 2. XVS accrued at the new speed starts after this block.\\n\\n updateVenusSupplyIndex(address(vToken));\\n // Update speed and emit event\\n venusSupplySpeeds[address(vToken)] = supplySpeed;\\n emit VenusSupplySpeedUpdated(vToken, supplySpeed);\\n }\\n\\n if (venusBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n // Borrow speed updated so let's update borrow state to ensure that\\n // 1. XVS accrued properly for the old speed, and\\n // 2. XVS accrued at the new speed starts after this block.\\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n updateVenusBorrowIndex(address(vToken), borrowIndex);\\n\\n // Update speed and emit event\\n venusBorrowSpeeds[address(vToken)] = borrowSpeed;\\n emit VenusBorrowSpeedUpdated(vToken, borrowSpeed);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x19e28f481bd47db3871b1ae379608c22c59b7d331b471eab7c972068403588e3\"},\"contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\n\\n/**\\n * @title XVSRewardsHelper\\n * @author Venus\\n * @dev This contract contains internal functions used in RewardFacet and PolicyFacet\\n * @notice This facet contract contains the shared functions used by the RewardFacet and PolicyFacet\\n */\\ncontract XVSRewardsHelper is FacetBase {\\n /// @notice Emitted when XVS is distributed to a borrower\\n event DistributedBorrowerVenus(\\n VToken indexed vToken,\\n address indexed borrower,\\n uint256 venusDelta,\\n uint256 venusBorrowIndex\\n );\\n\\n /// @notice Emitted when XVS is distributed to a supplier\\n event DistributedSupplierVenus(\\n VToken indexed vToken,\\n address indexed supplier,\\n uint256 venusDelta,\\n uint256 venusSupplyIndex\\n );\\n\\n /**\\n * @notice Accrue XVS to the market by updating the borrow index\\n * @param vToken The market whose borrow index to update\\n */\\n function updateVenusBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n VenusMarketState storage borrowState = venusBorrowState[vToken];\\n uint256 borrowSpeed = venusBorrowSpeeds[vToken];\\n uint32 blockNumber = getBlockNumberAsUint32();\\n uint256 deltaBlocks = sub_(blockNumber, borrowState.block);\\n if (deltaBlocks != 0 && borrowSpeed != 0) {\\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n uint256 accruedVenus = mul_(deltaBlocks, borrowSpeed);\\n Double memory ratio = borrowAmount != 0 ? fraction(accruedVenus, borrowAmount) : Double({ mantissa: 0 });\\n borrowState.index = safe224(add_(Double({ mantissa: borrowState.index }), ratio).mantissa, \\\"224\\\");\\n borrowState.block = blockNumber;\\n } else if (deltaBlocks != 0) {\\n borrowState.block = blockNumber;\\n }\\n }\\n\\n /**\\n * @notice Accrue XVS to the market by updating the supply index\\n * @param vToken The market whose supply index to update\\n */\\n function updateVenusSupplyIndex(address vToken) internal {\\n VenusMarketState storage supplyState = venusSupplyState[vToken];\\n uint256 supplySpeed = venusSupplySpeeds[vToken];\\n uint32 blockNumber = getBlockNumberAsUint32();\\n\\n uint256 deltaBlocks = sub_(blockNumber, supplyState.block);\\n if (deltaBlocks != 0 && supplySpeed != 0) {\\n uint256 supplyTokens = VToken(vToken).totalSupply();\\n uint256 accruedVenus = mul_(deltaBlocks, supplySpeed);\\n Double memory ratio = supplyTokens != 0 ? fraction(accruedVenus, supplyTokens) : Double({ mantissa: 0 });\\n supplyState.index = safe224(add_(Double({ mantissa: supplyState.index }), ratio).mantissa, \\\"224\\\");\\n supplyState.block = blockNumber;\\n } else if (deltaBlocks != 0) {\\n supplyState.block = blockNumber;\\n }\\n }\\n\\n /**\\n * @notice Calculate XVS accrued by a supplier and possibly transfer it to them\\n * @param vToken The market in which the supplier is interacting\\n * @param supplier The address of the supplier to distribute XVS to\\n */\\n function distributeSupplierVenus(address vToken, address supplier) internal {\\n if (address(vaiVaultAddress) != address(0)) {\\n releaseToVault();\\n }\\n uint256 supplyIndex = venusSupplyState[vToken].index;\\n uint256 supplierIndex = venusSupplierIndex[vToken][supplier];\\n // Update supplier's index to the current index since we are distributing accrued XVS\\n venusSupplierIndex[vToken][supplier] = supplyIndex;\\n if (supplierIndex == 0 && supplyIndex >= venusInitialIndex) {\\n // Covers the case where users supplied tokens before the market's supply state index was set.\\n // Rewards the user with XVS accrued from the start of when supplier rewards were first\\n // set for the market.\\n supplierIndex = venusInitialIndex;\\n }\\n // Calculate change in the cumulative sum of the XVS per vToken accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n // Multiply of supplierTokens and supplierDelta\\n uint256 supplierDelta = mul_(VToken(vToken).balanceOf(supplier), deltaIndex);\\n // Addition of supplierAccrued and supplierDelta\\n venusAccrued[supplier] = add_(venusAccrued[supplier], supplierDelta);\\n emit DistributedSupplierVenus(VToken(vToken), supplier, supplierDelta, supplyIndex);\\n }\\n\\n /**\\n * @notice Calculate XVS accrued by a borrower and possibly transfer it to them\\n * @dev Borrowers will not begin to accrue until after the first interaction with the protocol\\n * @param vToken The market in which the borrower is interacting\\n * @param borrower The address of the borrower to distribute XVS to\\n */\\n function distributeBorrowerVenus(address vToken, address borrower, Exp memory marketBorrowIndex) internal {\\n if (address(vaiVaultAddress) != address(0)) {\\n releaseToVault();\\n }\\n uint256 borrowIndex = venusBorrowState[vToken].index;\\n uint256 borrowerIndex = venusBorrowerIndex[vToken][borrower];\\n // Update borrowers's index to the current index since we are distributing accrued XVS\\n venusBorrowerIndex[vToken][borrower] = borrowIndex;\\n if (borrowerIndex == 0 && borrowIndex >= venusInitialIndex) {\\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n // Rewards the user with XVS accrued from the start of when borrower rewards were first\\n // set for the market.\\n borrowerIndex = venusInitialIndex;\\n }\\n // Calculate change in the cumulative sum of the XVS per borrowed unit accrued\\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n uint256 borrowerDelta = mul_(div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex);\\n venusAccrued[borrower] = add_(venusAccrued[borrower], borrowerDelta);\\n emit DistributedBorrowerVenus(VToken(vToken), borrower, borrowerDelta, borrowIndex);\\n }\\n}\\n\",\"keccak256\":\"0xf13ee35960223103dfc4a661771ae73998d4d4ff5b27f37bbaa52409bbc6103b\"},\"contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface IPolicyFacet {\\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256);\\n\\n function mintVerify(address vToken, address minter, uint256 mintAmount, uint256 mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256);\\n\\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256);\\n\\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint256 repayAmount\\n ) external returns (uint256);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint256 repayAmount,\\n uint256 borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount\\n ) external view returns (uint256);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint256 repayAmount,\\n uint256 seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external returns (uint256);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint256 seizeTokens\\n ) external;\\n\\n function transferAllowed(\\n address vToken,\\n address src,\\n address dst,\\n uint256 transferTokens\\n ) external returns (uint256);\\n\\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external;\\n\\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);\\n\\n function getHypotheticalAccountLiquidity(\\n address account,\\n address vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) external view returns (uint256, uint256, uint256);\\n\\n function _setVenusSpeeds(\\n VToken[] calldata vTokens,\\n uint256[] calldata supplySpeeds,\\n uint256[] calldata borrowSpeeds\\n ) external;\\n}\\n\",\"keccak256\":\"0xbcbbf088aa79d3fcc6945cfbff35b1f2591a803efa6344da1cbf2575f14713be\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport { VTokenInterface } from \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function mintVAI(uint256 mintVAIAmount) external returns (uint256);\\n\\n function repayVAI(uint256 amount) external returns (uint256, uint256);\\n\\n function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256);\\n\\n function liquidateVAI(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint256, uint256);\\n\\n function getMintableVAI(address minter) external view returns (uint256, uint256);\\n\\n function getVAIAddress() external view returns (address);\\n\\n function getVAIRepayAmount(address account) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x1f020ff46cb0efa0ebf563f449fd4d8aa1c8b8ed53c46860d71a08548d7fdfaa\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK,\\n UNLIST_MARKET_NOT_LISTED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0x4f5a41ef380336395706659e2b8f315870dcf3d617ea6f81104424500b15b1ef\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061369b806100206000396000f3fe608060405234801561001057600080fd5b50600436106103af5760003560e01c80637d172bd5116101f4578063c5b4db551161011a578063e37d4b79116100ad578063ead1a8a01161007c578063ead1a8a014610b88578063f445d70314610c96578063f851a44014610cc4578063fa6331d814610ccc576103af565b8063e37d4b7914610af5578063e85a296014610b1b578063e875544614610b4a578063eabe7d9114610b52576103af565b8063d3270f99116100e9578063d3270f9914610a83578063da3d454c14610a8b578063dce1544914610ac1578063dcfbc0c714610aed576103af565b8063c5b4db5514610a09578063c5f956af14610a2d578063c7ee005e14610a35578063d02f735114610a3d576103af565b80639bb27d6211610192578063bbb8864a11610161578063bbb8864a14610997578063bdcdc258146109bd578063bec04f72146109f9578063bf32442d14610a01576103af565b80639bb27d6214610931578063b2eafc3914610939578063b8324c7c14610941578063bb82aa5e1461098f576103af565b80638c1ac18a116101ce5780638c1ac18a146108b35780638e8f294b146108d95780639254f5e51461092157806394b2294b14610929576103af565b80637d172bd51461087d5780637dc0d1d0146108855780638a7dc1651461088d576103af565b806347ef3b3b116102d95780635c778605116102775780636a56947e116102465780636a56947e146107eb5780636d35bf9114610827578063719f701b1461086d5780637655138314610875576103af565b80635c778605146107235780635dd3fc9d146107595780635ec88c791461077f5780635fc7e71e146107a5576103af565b80634e79238f116102b35780634e79238f1461063a5780634ef4c3e11461069457806351dff989146106ca57806352d84d1e14610706576103af565b806347ef3b3b146105c05780634a5844321461060c5780634ada90af14610632576103af565b806324008a62116103515780634088c73e116103205780634088c73e1461054657806341a18d2c1461054e57806341c728b91461057c578063425fad58146105b8576103af565b806324008a62146104d457806324a3d6221461051057806326782247146105185780632bc7e29e14610520576103af565b80630db4b4e51161038d5780630db4b4e51461042257806310b983381461042a5780631ededc911461046c57806321af4569146104b0576103af565b806302c3bcbb146103b457806304ef9d58146103ec57806308e0225c146103f4575b600080fd5b6103da600480360360208110156103ca57600080fd5b50356001600160a01b0316610cd4565b60408051918252519081900360200190f35b6103da610ce6565b6103da6004803603604081101561040a57600080fd5b506001600160a01b0381358116916020013516610cec565b6103da610d09565b6104586004803603604081101561044057600080fd5b506001600160a01b0381358116916020013516610d0f565b604080519115158252519081900360200190f35b6104ae600480360360a081101561048257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135610d2f565b005b6104b8610db6565b604080516001600160a01b039092168252519081900360200190f35b6103da600480360360808110156104ea57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610dc5565b6104b8610e9a565b6104b8610ea9565b6103da6004803603602081101561053657600080fd5b50356001600160a01b0316610eb8565b610458610eca565b6103da6004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610ed3565b6104ae6004803603608081101561059257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610ef0565b610458610f76565b6104ae600480360360c08110156105d657600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135610f85565b6103da6004803603602081101561062257600080fd5b50356001600160a01b031661107b565b6103da61108d565b6106766004803603608081101561065057600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611093565b60408051938452602084019290925282820152519081900360600190f35b6103da600480360360608110156106aa57600080fd5b506001600160a01b038135811691602081013590911690604001356110c9565b6104ae600480360360808110156106e057600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112cf565b6104b86004803603602081101561071c57600080fd5b5035611320565b6104ae6004803603606081101561073957600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6103da6004803603602081101561076f57600080fd5b50356001600160a01b03166113cc565b6106766004803603602081101561079557600080fd5b50356001600160a01b03166113de565b6103da600480360360a08110156107bb57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611413565b6104ae6004803603608081101561080157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356116ae565b6104ae600480360360a081101561083d57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611783565b6103da611858565b61045861185e565b6104b861186c565b6104b861187b565b6103da600480360360208110156108a357600080fd5b50356001600160a01b031661188a565b610458600480360360208110156108c957600080fd5b50356001600160a01b031661189c565b6108ff600480360360208110156108ef57600080fd5b50356001600160a01b03166118b1565b6040805193151584526020840192909252151582820152519081900360600190f35b6104b86118d7565b6103da6118e6565b6104b86118ec565b6104b86118fb565b6109676004803603602081101561095757600080fd5b50356001600160a01b031661190a565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104b8611934565b6103da600480360360208110156109ad57600080fd5b50356001600160a01b0316611943565b6103da600480360360808110156109d357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611955565b6103da6119a3565b6104b86119a9565b610a116119b8565b604080516001600160e01b039092168252519081900360200190f35b6104b86119ca565b6104b86119d9565b6103da600480360360a0811015610a5357600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356119e8565b6104b8611b91565b6103da60048036036060811015610aa157600080fd5b506001600160a01b03813581169160208101359091169060400135611ba0565b6104b860048036036040811015610ad757600080fd5b506001600160a01b038135169060200135611f39565b6104b8611f6e565b61096760048036036020811015610b0b57600080fd5b50356001600160a01b0316611f7d565b61045860048036036040811015610b3157600080fd5b5080356001600160a01b0316906020013560ff16611fa7565b6103da611fe9565b6103da60048036036060811015610b6857600080fd5b506001600160a01b03813581169160208101359091169060400135611fef565b6104ae60048036036060811015610b9e57600080fd5b810190602081018135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460208302840111600160201b83111715610beb57600080fd5b919390929091602081019035600160201b811115610c0857600080fd5b820183602082011115610c1a57600080fd5b803590602001918460208302840111600160201b83111715610c3b57600080fd5b919390929091602081019035600160201b811115610c5857600080fd5b820183602082011115610c6a57600080fd5b803590602001918460208302840111600160201b83111715610c8b57600080fd5b50909250905061203e565b61045860048036036040811015610cac57600080fd5b506001600160a01b0381358116916020013516612117565b6104b8612137565b6103da612146565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03868116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050505b5050505050565b601e546001600160a01b031681565b6000610dcf61214c565b610dda8560036121a1565b6001600160a01b0385166000908152600960205260409020610dfb906121f4565b610e03613629565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4757600080fd5b505afa158015610e5b573d6000803e3d6000fd5b505050506040513d6020811015610e7157600080fd5b505190529050610e818682612241565b610e8c8685836123f7565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610f5757600080fd5b505af1158015610f6b573d6000803e3d6000fd5b505050505b50505050565b60185462010000900460ff1681565b6031546001600160a01b03161561107357603154604080516367994e8b60e11b81526001600160a01b03868116600483015289811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0389811660048301528b81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b15801561105a57600080fd5b505af115801561106e573d6000803e3d6000fd5b505050505b505050505050565b601f6020526000908152604090205481565b60065481565b6000806000806000806110a88a8a8a8a612597565b9250925092508260138111156110ba57fe5b9a919950975095505050505050565b60006110d361214c565b6110de8460006121a1565b6001600160a01b03841660009081526009602052604090206110ff906121f4565b6001600160a01b03841660009081526027602052604090205480611163576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420737570706c792063617020697320360541b604482015290519081900360640190fd5b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119e57600080fd5b505afa1580156111b2573d6000803e3d6000fd5b505050506040513d60208110156111c857600080fd5b505190506111d4613629565b6040518060200160405280886001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561121857600080fd5b505afa15801561122c573d6000803e3d6000fd5b505050506040513d602081101561124257600080fd5b5051905290506000611255828488612656565b9050838111156112ac576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420737570706c7920636170207265616368656400000000000000604482015290519081900360640190fd5b6112b58861267e565b6112bf888861280a565b60009450505050505b9392505050565b801515806112db575081155b610ef0576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d818154811061132d57fe5b6000918252602090912001546001600160a01b0316905081565b6031546001600160a01b0316156113c757603154604080516367994e8b60e11b81526001600160a01b03858116600483015286811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156113ae57600080fd5b505af11580156113c2573d6000803e3d6000fd5b505050505b505050565b602b6020526000908152604090205481565b6000806000806000806113f5876000806000612597565b92509250925082601381111561140757fe5b97919650945092505050565b600061141d61214c565b6114288660056121a1565b6025546001600160a01b03161580159061145057506025546001600160a01b03858116911614155b1561145d575060016116a5565b6001600160a01b038516600090815260096020526040902061147e906121f4565b6015546000906001600160a01b03888116911614611540576001600160a01b03871660009081526009602052604090206114b7906121f4565b866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b505190506115bc565b60155460408051633c617c9160e11b81526001600160a01b038781166004830152915191909216916378c2f922916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505190505b6001600160a01b0387166000908152602d602052604090205460ff168061160857506001600160a01b038085166000908152603260209081526040808320938b168352929052205460ff165b1561162757808311156116205760115b9150506116a5565b6000611618565b600080611638866000806000612597565b9193509091506000905082601381111561164e57fe5b146116695781601381111561165f57fe5b93505050506116a5565b8061167557600361165f565b61168f6040518060200160405280600554815250846129d2565b85111561169d57601161165f565b600093505050505b95945050505050565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b15801561171557600080fd5b505af1158015611729573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0387811660048301528981166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610f5757600080fd5b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03858116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156117ea57600080fd5b505af11580156117fe573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0388811660048301528a81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610d9657600080fd5b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b60075481565b6025546001600160a01b031681565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b600061195f61214c565b61196a8560066121a1565b60006119778686856129f1565b90508015611986579050610e92565b61198f8661267e565b611999868661280a565b610e8c868561280a565b60175481565b6033546001600160a01b031690565b6a0c097ce7bc90715b34b9f160241b81565b6021546001600160a01b031681565b6031546001600160a01b031681565b60006119f261214c565b6119fd8660046121a1565b6001600160a01b0386166000908152600960205260409020611a1e816121f4565b6001600160a01b038416600090815260028201602052604090205460ff16611a47576013611618565b6015546001600160a01b03878116911614611a7d576001600160a01b0386166000908152600960205260409020611a7d906121f4565b856001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505160408051635fe3b56760e01b815290516001600160a01b03928316928a1691635fe3b567916004808301926020929190829003018186803b158015611b2657600080fd5b505afa158015611b3a573d6000803e3d6000fd5b505050506040513d6020811015611b5057600080fd5b50516001600160a01b031614611b67576002611618565b611b708761267e565b611b7a878561280a565b611b84878661280a565b6000979650505050505050565b6026546001600160a01b031681565b6000611baa61214c565b611bb58460026121a1565b6001600160a01b0384166000908152600960205260409020611bd6906121f4565b6001600160a01b0384166000908152601f602052604090205480611c3a576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420626f72726f772063617020697320360541b604482015290519081900360640190fd5b6001600160a01b038086166000908152600960209081526040808320938816835260029093019052205460ff16611cf857336001600160a01b03861614611cc0576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba103132903b2a37b5b2b760591b604482015290519081900360640190fd5b6000611ccc8686612a9b565b90506000816013811115611cdc57fe5b14611cf657806013811115611ced57fe5b925050506112c8565b505b600480546040805163fc57d4df60e01b81526001600160a01b03898116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015611d4957600080fd5b505afa158015611d5d573d6000803e3d6000fd5b505050506040513d6020811015611d7357600080fd5b5051611d8357600d9150506112c8565b6000611df3866001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015611dc157600080fd5b505afa158015611dd5573d6000803e3d6000fd5b505050506040513d6020811015611deb57600080fd5b505185612b7f565b905081811115611e4a576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b600080611e5a8789600089612597565b91935090915060009050826013811115611e7057fe5b14611e8c57816013811115611e8157fe5b9450505050506112c8565b8015611e99576004611e81565b611ea1613629565b60405180602001604052808a6001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ee557600080fd5b505afa158015611ef9573d6000803e3d6000fd5b505050506040513d6020811015611f0f57600080fd5b505190529050611f1f8982612241565b611f2a8989836123f7565b60009998505050505050505050565b60086020528160005260406000208181548110611f5257fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b038216600090815260296020526040812081836008811115611fcc57fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b6000611ff961214c565b6120048460016121a1565b60006120118585856129f1565b905080156120205790506112c8565b6120298561267e565b612033858561280a565b600095945050505050565b612046612bb5565b84838114801561205557508082145b612096576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b81811015610f6b576120c58888838181106120b057fe5b905060200201356001600160a01b0316612c05565b61210f8888838181106120d457fe5b905060200201356001600160a01b03168787848181106120f057fe5b9050602002013586868581811061210357fe5b90506020020135612c58565b600101612099565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b60185462010000900460ff161561219f576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b565b6121ab8282611fa7565b156121f0576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b5050565b805460ff1661223e576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b50565b6001600160a01b0382166000908152601160209081526040808320602a909252822054909161226e612ded565b83549091506000906122909063ffffffff80851691600160e01b900416612e2e565b905080158015906122a057508215155b156123cc576000612315876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156122e357600080fd5b505afa1580156122f7573d6000803e3d6000fd5b505050506040513d602081101561230d57600080fd5b505187612e68565b905060006123238386612e86565b905061232d613629565b826123475760405180602001604052806000815250612351565b6123518284612ec8565b604080516020810190915288546001600160e01b0316815290915061239a9061237a9083612f05565b516040805180820190915260038152620c8c8d60ea1b6020820152612f2a565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611073915050565b801561107357835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b601b546001600160a01b03161561241057612410612fc4565b6001600160a01b0383811660009081526011602090815260408083205460138352818420948716845293909152902080546001600160e01b0390921690819055908015801561246d57506a0c097ce7bc90715b34b9f160241b8210155b1561248357506a0c097ce7bc90715b34b9f160241b5b61248b613629565b60405180602001604052806124a08585612e2e565b81525090506000612509612503886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156122e357600080fd5b8361316c565b6001600160a01b03871660009081526014602052604090205490915061252f9082612b7f565b6001600160a01b0380881660008181526014602090815260409182902094909455805185815293840188905280519193928b16927f837bdc11fca9f17ce44167944475225a205279b17e88c791c3b1f66f354668fb929081900390910190a350505050505050565b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b15801561260a57600080fd5b505afa15801561261e573d6000803e3d6000fd5b505050506040513d606081101561263457600080fd5b508051602082015160409092015190945090925090508260138111156110ba57fe5b6000612660613629565b61266a858561319a565b90506116a5612678826131bb565b84612b7f565b6001600160a01b0381166000908152601060209081526040808320602b90925282205490916126ab612ded565b83549091506000906126cd9063ffffffff80851691600160e01b900416612e2e565b905080158015906126dd57508215155b156127e0576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561271d57600080fd5b505afa158015612731573d6000803e3d6000fd5b505050506040513d602081101561274757600080fd5b5051905060006127578386612e86565b9050612761613629565b8261277b5760405180602001604052806000815250612785565b6127858284612ec8565b604080516020810190915288546001600160e01b031681529091506127ae9061237a9083612f05565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550610daf915050565b8015610daf57835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b601b546001600160a01b03161561282357612823612fc4565b6001600160a01b0382811660009081526010602090815260408083205460128352818420948616845293909152902080546001600160e01b0390921690819055908015801561288057506a0c097ce7bc90715b34b9f160241b8210155b1561289657506a0c097ce7bc90715b34b9f160241b5b61289e613629565b60405180602001604052806128b38585612e2e565b81525090506000612945866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561291357600080fd5b505afa158015612927573d6000803e3d6000fd5b505050506040513d602081101561293d57600080fd5b50518361316c565b6001600160a01b03861660009081526014602052604090205490915061296b9082612b7f565b6001600160a01b0380871660008181526014602090815260409182902094909455805185815293840188905280519193928a16927ffa9d964d891991c113b49e3db1932abd6c67263d387119707aafdd6c4010a3a9929081900390910190a3505050505050565b60006129dc613629565b6129e6848461319a565b9050610e92816131bb565b6001600160a01b0383166000908152600960205260408120612a12906121f4565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16612a4b575060006112c8565b600080612a5b8587866000612597565b91935090915060009050826013811115612a7157fe5b14612a8257816013811115611ced57fe5b8015612a8f576004611ced565b60009695505050505050565b6000612aa88360076121a1565b6001600160a01b0383166000908152600960205260409020612ac9816121f4565b6001600160a01b038316600090815260028201602052604090205460ff1615612af6576000915050611fe3565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b60006112c88383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b8152506131ca565b6000546001600160a01b0316331461219f576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b6001600160a01b03811661223e576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612c79906121f4565b6001600160a01b0383166000908152602b60205260409020548214612cf257612ca18361267e565b6001600160a01b0383166000818152602b6020908152604091829020859055815185815291517fa9ff26899e4982e7634afa9f70115dcfb61a17d6e8cdd91aa837671d0ff40ba69281900390910190a25b6001600160a01b0383166000908152602a602052604090205481146113c757612d19613629565b6040518060200160405280856001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d5d57600080fd5b505afa158015612d71573d6000803e3d6000fd5b505050506040513d6020811015612d8757600080fd5b505190529050612d978482612241565b6001600160a01b0384166000818152602a6020908152604091829020859055815185815291517f0c62c1bc89ec4c40dccb4d21543e782c5ba43897c0075d108d8964181ea3c51b9281900390910190a250505050565b6000612e29612dfa613228565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b81525061322c565b905090565b60006112c88383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250613281565b60006112c8612e7f84670de0b6b3a7640000612e86565b83516132db565b60006112c883836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f7700000000000000000081525061330e565b612ed0613629565b6040518060200160405280612efc612ef6866a0c097ce7bc90715b34b9f160241b612e86565b856132db565b90529392505050565b612f0d613629565b6040518060200160405280612efc85600001518560000151612b7f565b600081600160e01b8410612fbc5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612f81578181015183820152602001612f69565b50505050905090810190601f168015612fae5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b601c541580612fdb5750601c54612fd9613228565b105b15612fe55761219f565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561303557600080fd5b505afa158015613049573d6000803e3d6000fd5b505050506040513d602081101561305f57600080fd5b505190508061306f57505061219f565b60008061308561307d613228565b601c54612e2e565b90506000613095601a5483612e86565b90508084106130a6578092506130aa565b8392505b601d548310156130be57505050505061219f565b6130c6613228565b601c55601b546130e9906001600160a01b0387811691168563ffffffff61338416565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d9657600080fd5b60006a0c097ce7bc90715b34b9f160241b61318b848460000151612e86565b8161319257fe5b049392505050565b6131a2613629565b6040518060200160405280612efc856000015185612e86565b51670de0b6b3a7640000900490565b6000838301828582101561321f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b50949350505050565b4390565b600081600160201b8410612fbc5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b600081848411156132d35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b505050900390565b60006112c883836040518060400160405280600e81526020016d646976696465206279207a65726f60901b8152506133d6565b600083158061331b575082155b15613328575060006112c8565b8383028385828161333557fe5b0414839061321f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113c7908490613438565b600081836134255760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b5082848161342f57fe5b04949350505050565b61344a826001600160a01b03166135f0565b61349b576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106134d95780518252601f1990920191602091820191016134ba565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461353b576040519150601f19603f3d011682016040523d82523d6000602084013e613540565b606091505b509150915081613597576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610f70578080602001905160208110156135b357600080fd5b5051610f705760405162461bcd60e51b815260040180806020018281038252602a81526020018061363d602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e92575050151592915050565b604051806020016040528060008152509056fe5361666542455032303a204245503230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a723158203f58b21f29192df605dc656de953c22c19c0c55e6740cb388aa793a126d9ecb464736f6c63430005100032", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103af5760003560e01c80637d172bd5116101f4578063c5b4db551161011a578063e37d4b79116100ad578063ead1a8a01161007c578063ead1a8a014610b88578063f445d70314610c96578063f851a44014610cc4578063fa6331d814610ccc576103af565b8063e37d4b7914610af5578063e85a296014610b1b578063e875544614610b4a578063eabe7d9114610b52576103af565b8063d3270f99116100e9578063d3270f9914610a83578063da3d454c14610a8b578063dce1544914610ac1578063dcfbc0c714610aed576103af565b8063c5b4db5514610a09578063c5f956af14610a2d578063c7ee005e14610a35578063d02f735114610a3d576103af565b80639bb27d6211610192578063bbb8864a11610161578063bbb8864a14610997578063bdcdc258146109bd578063bec04f72146109f9578063bf32442d14610a01576103af565b80639bb27d6214610931578063b2eafc3914610939578063b8324c7c14610941578063bb82aa5e1461098f576103af565b80638c1ac18a116101ce5780638c1ac18a146108b35780638e8f294b146108d95780639254f5e51461092157806394b2294b14610929576103af565b80637d172bd51461087d5780637dc0d1d0146108855780638a7dc1651461088d576103af565b806347ef3b3b116102d95780635c778605116102775780636a56947e116102465780636a56947e146107eb5780636d35bf9114610827578063719f701b1461086d5780637655138314610875576103af565b80635c778605146107235780635dd3fc9d146107595780635ec88c791461077f5780635fc7e71e146107a5576103af565b80634e79238f116102b35780634e79238f1461063a5780634ef4c3e11461069457806351dff989146106ca57806352d84d1e14610706576103af565b806347ef3b3b146105c05780634a5844321461060c5780634ada90af14610632576103af565b806324008a62116103515780634088c73e116103205780634088c73e1461054657806341a18d2c1461054e57806341c728b91461057c578063425fad58146105b8576103af565b806324008a62146104d457806324a3d6221461051057806326782247146105185780632bc7e29e14610520576103af565b80630db4b4e51161038d5780630db4b4e51461042257806310b983381461042a5780631ededc911461046c57806321af4569146104b0576103af565b806302c3bcbb146103b457806304ef9d58146103ec57806308e0225c146103f4575b600080fd5b6103da600480360360208110156103ca57600080fd5b50356001600160a01b0316610cd4565b60408051918252519081900360200190f35b6103da610ce6565b6103da6004803603604081101561040a57600080fd5b506001600160a01b0381358116916020013516610cec565b6103da610d09565b6104586004803603604081101561044057600080fd5b506001600160a01b0381358116916020013516610d0f565b604080519115158252519081900360200190f35b6104ae600480360360a081101561048257600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060800135610d2f565b005b6104b8610db6565b604080516001600160a01b039092168252519081900360200190f35b6103da600480360360808110156104ea57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610dc5565b6104b8610e9a565b6104b8610ea9565b6103da6004803603602081101561053657600080fd5b50356001600160a01b0316610eb8565b610458610eca565b6103da6004803603604081101561056457600080fd5b506001600160a01b0381358116916020013516610ed3565b6104ae6004803603608081101561059257600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610ef0565b610458610f76565b6104ae600480360360c08110156105d657600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135610f85565b6103da6004803603602081101561062257600080fd5b50356001600160a01b031661107b565b6103da61108d565b6106766004803603608081101561065057600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611093565b60408051938452602084019290925282820152519081900360600190f35b6103da600480360360608110156106aa57600080fd5b506001600160a01b038135811691602081013590911690604001356110c9565b6104ae600480360360808110156106e057600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112cf565b6104b86004803603602081101561071c57600080fd5b5035611320565b6104ae6004803603606081101561073957600080fd5b506001600160a01b03813581169160208101359091169060400135611347565b6103da6004803603602081101561076f57600080fd5b50356001600160a01b03166113cc565b6106766004803603602081101561079557600080fd5b50356001600160a01b03166113de565b6103da600480360360a08110156107bb57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611413565b6104ae6004803603608081101561080157600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356116ae565b6104ae600480360360a081101561083d57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135611783565b6103da611858565b61045861185e565b6104b861186c565b6104b861187b565b6103da600480360360208110156108a357600080fd5b50356001600160a01b031661188a565b610458600480360360208110156108c957600080fd5b50356001600160a01b031661189c565b6108ff600480360360208110156108ef57600080fd5b50356001600160a01b03166118b1565b6040805193151584526020840192909252151582820152519081900360600190f35b6104b86118d7565b6103da6118e6565b6104b86118ec565b6104b86118fb565b6109676004803603602081101561095757600080fd5b50356001600160a01b031661190a565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104b8611934565b6103da600480360360208110156109ad57600080fd5b50356001600160a01b0316611943565b6103da600480360360808110156109d357600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611955565b6103da6119a3565b6104b86119a9565b610a116119b8565b604080516001600160e01b039092168252519081900360200190f35b6104b86119ca565b6104b86119d9565b6103da600480360360a0811015610a5357600080fd5b506001600160a01b03813581169160208101358216916040820135811691606081013590911690608001356119e8565b6104b8611b91565b6103da60048036036060811015610aa157600080fd5b506001600160a01b03813581169160208101359091169060400135611ba0565b6104b860048036036040811015610ad757600080fd5b506001600160a01b038135169060200135611f39565b6104b8611f6e565b61096760048036036020811015610b0b57600080fd5b50356001600160a01b0316611f7d565b61045860048036036040811015610b3157600080fd5b5080356001600160a01b0316906020013560ff16611fa7565b6103da611fe9565b6103da60048036036060811015610b6857600080fd5b506001600160a01b03813581169160208101359091169060400135611fef565b6104ae60048036036060811015610b9e57600080fd5b810190602081018135600160201b811115610bb857600080fd5b820183602082011115610bca57600080fd5b803590602001918460208302840111600160201b83111715610beb57600080fd5b919390929091602081019035600160201b811115610c0857600080fd5b820183602082011115610c1a57600080fd5b803590602001918460208302840111600160201b83111715610c3b57600080fd5b919390929091602081019035600160201b811115610c5857600080fd5b820183602082011115610c6a57600080fd5b803590602001918460208302840111600160201b83111715610c8b57600080fd5b50909250905061203e565b61045860048036036040811015610cac57600080fd5b506001600160a01b0381358116916020013516612117565b6104b8612137565b6103da612146565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03868116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610d9657600080fd5b505af1158015610daa573d6000803e3d6000fd5b505050505b5050505050565b601e546001600160a01b031681565b6000610dcf61214c565b610dda8560036121a1565b6001600160a01b0385166000908152600960205260409020610dfb906121f4565b610e03613629565b6040518060200160405280876001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4757600080fd5b505afa158015610e5b573d6000803e3d6000fd5b505050506040513d6020811015610e7157600080fd5b505190529050610e818682612241565b610e8c8685836123f7565b60009150505b949350505050565b600a546001600160a01b031681565b6001546001600160a01b031681565b60166020526000908152604090205481565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610f5757600080fd5b505af1158015610f6b573d6000803e3d6000fd5b505050505b50505050565b60185462010000900460ff1681565b6031546001600160a01b03161561107357603154604080516367994e8b60e11b81526001600160a01b03868116600483015289811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b158015610fec57600080fd5b505af1158015611000573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0389811660048301528b81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b15801561105a57600080fd5b505af115801561106e573d6000803e3d6000fd5b505050505b505050505050565b601f6020526000908152604090205481565b60065481565b6000806000806000806110a88a8a8a8a612597565b9250925092508260138111156110ba57fe5b9a919950975095505050505050565b60006110d361214c565b6110de8460006121a1565b6001600160a01b03841660009081526009602052604090206110ff906121f4565b6001600160a01b03841660009081526027602052604090205480611163576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420737570706c792063617020697320360541b604482015290519081900360640190fd5b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119e57600080fd5b505afa1580156111b2573d6000803e3d6000fd5b505050506040513d60208110156111c857600080fd5b505190506111d4613629565b6040518060200160405280886001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561121857600080fd5b505afa15801561122c573d6000803e3d6000fd5b505050506040513d602081101561124257600080fd5b5051905290506000611255828488612656565b9050838111156112ac576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420737570706c7920636170207265616368656400000000000000604482015290519081900360640190fd5b6112b58861267e565b6112bf888861280a565b60009450505050505b9392505050565b801515806112db575081155b610ef0576040805162461bcd60e51b815260206004820152601160248201527072656465656d546f6b656e73207a65726f60781b604482015290519081900360640190fd5b600d818154811061132d57fe5b6000918252602090912001546001600160a01b0316905081565b6031546001600160a01b0316156113c757603154604080516367994e8b60e11b81526001600160a01b03858116600483015286811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156113ae57600080fd5b505af11580156113c2573d6000803e3d6000fd5b505050505b505050565b602b6020526000908152604090205481565b6000806000806000806113f5876000806000612597565b92509250925082601381111561140757fe5b97919650945092505050565b600061141d61214c565b6114288660056121a1565b6025546001600160a01b03161580159061145057506025546001600160a01b03858116911614155b1561145d575060016116a5565b6001600160a01b038516600090815260096020526040902061147e906121f4565b6015546000906001600160a01b03888116911614611540576001600160a01b03871660009081526009602052604090206114b7906121f4565b866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b505190506115bc565b60155460408051633c617c9160e11b81526001600160a01b038781166004830152915191909216916378c2f922916024808301926020929190829003018186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d60208110156115b757600080fd5b505190505b6001600160a01b0387166000908152602d602052604090205460ff168061160857506001600160a01b038085166000908152603260209081526040808320938b168352929052205460ff165b1561162757808311156116205760115b9150506116a5565b6000611618565b600080611638866000806000612597565b9193509091506000905082601381111561164e57fe5b146116695781601381111561165f57fe5b93505050506116a5565b8061167557600361165f565b61168f6040518060200160405280600554815250846129d2565b85111561169d57601161165f565b600093505050505b95945050505050565b6031546001600160a01b031615610f7057603154604080516367994e8b60e11b81526001600160a01b03868116600483015287811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b15801561171557600080fd5b505af1158015611729573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0387811660048301528981166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610f5757600080fd5b6031546001600160a01b031615610daf57603154604080516367994e8b60e11b81526001600160a01b03858116600483015288811660248301529151919092169163cf329d1691604480830192600092919082900301818387803b1580156117ea57600080fd5b505af11580156117fe573d6000803e3d6000fd5b5050603154604080516367994e8b60e11b81526001600160a01b0388811660048301528a81166024830152915191909216935063cf329d169250604480830192600092919082900301818387803b158015610d9657600080fd5b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b6015546001600160a01b031681565b60075481565b6025546001600160a01b031681565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b602a6020526000908152604090205481565b600061195f61214c565b61196a8560066121a1565b60006119778686856129f1565b90508015611986579050610e92565b61198f8661267e565b611999868661280a565b610e8c868561280a565b60175481565b6033546001600160a01b031690565b6a0c097ce7bc90715b34b9f160241b81565b6021546001600160a01b031681565b6031546001600160a01b031681565b60006119f261214c565b6119fd8660046121a1565b6001600160a01b0386166000908152600960205260409020611a1e816121f4565b6001600160a01b038416600090815260028201602052604090205460ff16611a47576013611618565b6015546001600160a01b03878116911614611a7d576001600160a01b0386166000908152600960205260409020611a7d906121f4565b856001600160a01b0316635fe3b5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505160408051635fe3b56760e01b815290516001600160a01b03928316928a1691635fe3b567916004808301926020929190829003018186803b158015611b2657600080fd5b505afa158015611b3a573d6000803e3d6000fd5b505050506040513d6020811015611b5057600080fd5b50516001600160a01b031614611b67576002611618565b611b708761267e565b611b7a878561280a565b611b84878661280a565b6000979650505050505050565b6026546001600160a01b031681565b6000611baa61214c565b611bb58460026121a1565b6001600160a01b0384166000908152600960205260409020611bd6906121f4565b6001600160a01b0384166000908152601f602052604090205480611c3a576040805162461bcd60e51b815260206004820152601660248201527506d61726b657420626f72726f772063617020697320360541b604482015290519081900360640190fd5b6001600160a01b038086166000908152600960209081526040808320938816835260029093019052205460ff16611cf857336001600160a01b03861614611cc0576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba103132903b2a37b5b2b760591b604482015290519081900360640190fd5b6000611ccc8686612a9b565b90506000816013811115611cdc57fe5b14611cf657806013811115611ced57fe5b925050506112c8565b505b600480546040805163fc57d4df60e01b81526001600160a01b03898116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b158015611d4957600080fd5b505afa158015611d5d573d6000803e3d6000fd5b505050506040513d6020811015611d7357600080fd5b5051611d8357600d9150506112c8565b6000611df3866001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015611dc157600080fd5b505afa158015611dd5573d6000803e3d6000fd5b505050506040513d6020811015611deb57600080fd5b505185612b7f565b905081811115611e4a576040805162461bcd60e51b815260206004820152601960248201527f6d61726b657420626f72726f7720636170207265616368656400000000000000604482015290519081900360640190fd5b600080611e5a8789600089612597565b91935090915060009050826013811115611e7057fe5b14611e8c57816013811115611e8157fe5b9450505050506112c8565b8015611e99576004611e81565b611ea1613629565b60405180602001604052808a6001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ee557600080fd5b505afa158015611ef9573d6000803e3d6000fd5b505050506040513d6020811015611f0f57600080fd5b505190529050611f1f8982612241565b611f2a8989836123f7565b60009998505050505050505050565b60086020528160005260406000208181548110611f5257fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b038216600090815260296020526040812081836008811115611fcc57fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b6000611ff961214c565b6120048460016121a1565b60006120118585856129f1565b905080156120205790506112c8565b6120298561267e565b612033858561280a565b600095945050505050565b612046612bb5565b84838114801561205557508082145b612096576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b81811015610f6b576120c58888838181106120b057fe5b905060200201356001600160a01b0316612c05565b61210f8888838181106120d457fe5b905060200201356001600160a01b03168787848181106120f057fe5b9050602002013586868581811061210357fe5b90506020020135612c58565b600101612099565b603260209081526000928352604080842090915290825290205460ff1681565b6000546001600160a01b031681565b601a5481565b60185462010000900460ff161561219f576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b565b6121ab8282611fa7565b156121f0576040805162461bcd60e51b815260206004820152601060248201526f1858dd1a5bdb881a5cc81c185d5cd95960821b604482015290519081900360640190fd5b5050565b805460ff1661223e576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b50565b6001600160a01b0382166000908152601160209081526040808320602a909252822054909161226e612ded565b83549091506000906122909063ffffffff80851691600160e01b900416612e2e565b905080158015906122a057508215155b156123cc576000612315876001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156122e357600080fd5b505afa1580156122f7573d6000803e3d6000fd5b505050506040513d602081101561230d57600080fd5b505187612e68565b905060006123238386612e86565b905061232d613629565b826123475760405180602001604052806000815250612351565b6123518284612ec8565b604080516020810190915288546001600160e01b0316815290915061239a9061237a9083612f05565b516040805180820190915260038152620c8c8d60ea1b6020820152612f2a565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550611073915050565b801561107357835463ffffffff8316600160e01b026001600160e01b03909116178455505050505050565b601b546001600160a01b03161561241057612410612fc4565b6001600160a01b0383811660009081526011602090815260408083205460138352818420948716845293909152902080546001600160e01b0390921690819055908015801561246d57506a0c097ce7bc90715b34b9f160241b8210155b1561248357506a0c097ce7bc90715b34b9f160241b5b61248b613629565b60405180602001604052806124a08585612e2e565b81525090506000612509612503886001600160a01b03166395dd9193896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156122e357600080fd5b8361316c565b6001600160a01b03871660009081526014602052604090205490915061252f9082612b7f565b6001600160a01b0380881660008181526014602090815260409182902094909455805185815293840188905280519193928b16927f837bdc11fca9f17ce44167944475225a205279b17e88c791c3b1f66f354668fb929081900390910190a350505050505050565b6026546040805163a7032efb60e01b81523060048201526001600160a01b03878116602483015286811660448301526064820186905260848201859052915160009384938493849384938493169163a7032efb9160a4808301926060929190829003018186803b15801561260a57600080fd5b505afa15801561261e573d6000803e3d6000fd5b505050506040513d606081101561263457600080fd5b508051602082015160409092015190945090925090508260138111156110ba57fe5b6000612660613629565b61266a858561319a565b90506116a5612678826131bb565b84612b7f565b6001600160a01b0381166000908152601060209081526040808320602b90925282205490916126ab612ded565b83549091506000906126cd9063ffffffff80851691600160e01b900416612e2e565b905080158015906126dd57508215155b156127e0576000856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561271d57600080fd5b505afa158015612731573d6000803e3d6000fd5b505050506040513d602081101561274757600080fd5b5051905060006127578386612e86565b9050612761613629565b8261277b5760405180602001604052806000815250612785565b6127858284612ec8565b604080516020810190915288546001600160e01b031681529091506127ae9061237a9083612f05565b87546001600160e01b0319166001600160e01b039182161716600160e01b63ffffffff87160217875550610daf915050565b8015610daf57835463ffffffff8316600160e01b026001600160e01b039091161784555050505050565b601b546001600160a01b03161561282357612823612fc4565b6001600160a01b0382811660009081526010602090815260408083205460128352818420948616845293909152902080546001600160e01b0390921690819055908015801561288057506a0c097ce7bc90715b34b9f160241b8210155b1561289657506a0c097ce7bc90715b34b9f160241b5b61289e613629565b60405180602001604052806128b38585612e2e565b81525090506000612945866001600160a01b03166370a08231876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561291357600080fd5b505afa158015612927573d6000803e3d6000fd5b505050506040513d602081101561293d57600080fd5b50518361316c565b6001600160a01b03861660009081526014602052604090205490915061296b9082612b7f565b6001600160a01b0380871660008181526014602090815260409182902094909455805185815293840188905280519193928a16927ffa9d964d891991c113b49e3db1932abd6c67263d387119707aafdd6c4010a3a9929081900390910190a3505050505050565b60006129dc613629565b6129e6848461319a565b9050610e92816131bb565b6001600160a01b0383166000908152600960205260408120612a12906121f4565b6001600160a01b038085166000908152600960209081526040808320938716835260029093019052205460ff16612a4b575060006112c8565b600080612a5b8587866000612597565b91935090915060009050826013811115612a7157fe5b14612a8257816013811115611ced57fe5b8015612a8f576004611ced565b60009695505050505050565b6000612aa88360076121a1565b6001600160a01b0383166000908152600960205260409020612ac9816121f4565b6001600160a01b038316600090815260028201602052604090205460ff1615612af6576000915050611fe3565b6001600160a01b0380841660008181526002840160209081526040808320805460ff191660019081179091556008835281842080549182018155845291832090910180549489166001600160a01b031990951685179055519192917f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a59190a35060009392505050565b60006112c88383604051806040016040528060118152602001706164646974696f6e206f766572666c6f7760781b8152506131ca565b6000546001600160a01b0316331461219f576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b6001600160a01b03811661223e576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612c79906121f4565b6001600160a01b0383166000908152602b60205260409020548214612cf257612ca18361267e565b6001600160a01b0383166000818152602b6020908152604091829020859055815185815291517fa9ff26899e4982e7634afa9f70115dcfb61a17d6e8cdd91aa837671d0ff40ba69281900390910190a25b6001600160a01b0383166000908152602a602052604090205481146113c757612d19613629565b6040518060200160405280856001600160a01b031663aa5af0fd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612d5d57600080fd5b505afa158015612d71573d6000803e3d6000fd5b505050506040513d6020811015612d8757600080fd5b505190529050612d978482612241565b6001600160a01b0384166000818152602a6020908152604091829020859055815185815291517f0c62c1bc89ec4c40dccb4d21543e782c5ba43897c0075d108d8964181ea3c51b9281900390910190a250505050565b6000612e29612dfa613228565b60405180604001604052806011815260200170626c6f636b2023203e203332206269747360781b81525061322c565b905090565b60006112c88383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250613281565b60006112c8612e7f84670de0b6b3a7640000612e86565b83516132db565b60006112c883836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f7700000000000000000081525061330e565b612ed0613629565b6040518060200160405280612efc612ef6866a0c097ce7bc90715b34b9f160241b612e86565b856132db565b90529392505050565b612f0d613629565b6040518060200160405280612efc85600001518560000151612b7f565b600081600160e01b8410612fbc5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612f81578181015183820152602001612f69565b50505050905090810190601f168015612fae5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b601c541580612fdb5750601c54612fd9613228565b105b15612fe55761219f565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561303557600080fd5b505afa158015613049573d6000803e3d6000fd5b505050506040513d602081101561305f57600080fd5b505190508061306f57505061219f565b60008061308561307d613228565b601c54612e2e565b90506000613095601a5483612e86565b90508084106130a6578092506130aa565b8392505b601d548310156130be57505050505061219f565b6130c6613228565b601c55601b546130e9906001600160a01b0387811691168563ffffffff61338416565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d9657600080fd5b60006a0c097ce7bc90715b34b9f160241b61318b848460000151612e86565b8161319257fe5b049392505050565b6131a2613629565b6040518060200160405280612efc856000015185612e86565b51670de0b6b3a7640000900490565b6000838301828582101561321f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b50949350505050565b4390565b600081600160201b8410612fbc5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b600081848411156132d35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b505050900390565b60006112c883836040518060400160405280600e81526020016d646976696465206279207a65726f60901b8152506133d6565b600083158061331b575082155b15613328575060006112c8565b8383028385828161333557fe5b0414839061321f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113c7908490613438565b600081836134255760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612f81578181015183820152602001612f69565b5082848161342f57fe5b04949350505050565b61344a826001600160a01b03166135f0565b61349b576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106134d95780518252601f1990920191602091820191016134ba565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461353b576040519150601f19603f3d011682016040523d82523d6000602084013e613540565b606091505b509150915081613597576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610f70578080602001905160208110156135b357600080fd5b5051610f705760405162461bcd60e51b815260040180806020018281038252602a81526020018061363d602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e92575050151592915050565b604051806020016040528060008152509056fe5361666542455032303a204245503230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a723158203f58b21f29192df605dc656de953c22c19c0c55e6740cb388aa793a126d9ecb464736f6c63430005100032", "devdoc": { "author": "Venus", "details": "This facet contains all the hooks used while transferring the assets", @@ -1786,7 +1786,7 @@ "storageLayout": { "storage": [ { - "astId": 2391, + "astId": 2510, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "admin", "offset": 0, @@ -1794,7 +1794,7 @@ "type": "t_address" }, { - "astId": 2393, + "astId": 2512, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "pendingAdmin", "offset": 0, @@ -1802,7 +1802,7 @@ "type": "t_address" }, { - "astId": 2395, + "astId": 2514, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "comptrollerImplementation", "offset": 0, @@ -1810,7 +1810,7 @@ "type": "t_address" }, { - "astId": 2397, + "astId": 2516, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "pendingComptrollerImplementation", "offset": 0, @@ -1818,15 +1818,15 @@ "type": "t_address" }, { - "astId": 2404, + "astId": 2523, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "oracle", "offset": 0, "slot": "4", - "type": "t_contract(PriceOracle)12051" + "type": "t_contract(PriceOracle)12353" }, { - "astId": 2406, + "astId": 2525, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "closeFactorMantissa", "offset": 0, @@ -1834,7 +1834,7 @@ "type": "t_uint256" }, { - "astId": 2408, + "astId": 2527, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "liquidationIncentiveMantissa", "offset": 0, @@ -1842,7 +1842,7 @@ "type": "t_uint256" }, { - "astId": 2410, + "astId": 2529, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "maxAssets", "offset": 0, @@ -1850,23 +1850,23 @@ "type": "t_uint256" }, { - "astId": 2415, + "astId": 2534, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "accountAssets", "offset": 0, "slot": "8", - "type": "t_mapping(t_address,t_array(t_contract(VToken)22978)dyn_storage)" + "type": "t_mapping(t_address,t_array(t_contract(VToken)23491)dyn_storage)" }, { - "astId": 2430, + "astId": 2549, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "markets", "offset": 0, "slot": "9", - "type": "t_mapping(t_address,t_struct(Market)2426_storage)" + "type": "t_mapping(t_address,t_struct(Market)2545_storage)" }, { - "astId": 2432, + "astId": 2551, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "pauseGuardian", "offset": 0, @@ -1874,7 +1874,7 @@ "type": "t_address" }, { - "astId": 2434, + "astId": 2553, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_mintGuardianPaused", "offset": 20, @@ -1882,7 +1882,7 @@ "type": "t_bool" }, { - "astId": 2436, + "astId": 2555, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_borrowGuardianPaused", "offset": 21, @@ -1890,7 +1890,7 @@ "type": "t_bool" }, { - "astId": 2438, + "astId": 2557, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "transferGuardianPaused", "offset": 22, @@ -1898,7 +1898,7 @@ "type": "t_bool" }, { - "astId": 2440, + "astId": 2559, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "seizeGuardianPaused", "offset": 23, @@ -1906,7 +1906,7 @@ "type": "t_bool" }, { - "astId": 2444, + "astId": 2563, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "mintGuardianPaused", "offset": 0, @@ -1914,7 +1914,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2448, + "astId": 2567, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "borrowGuardianPaused", "offset": 0, @@ -1922,15 +1922,15 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2456, + "astId": 2575, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "allMarkets", "offset": 0, "slot": "13", - "type": "t_array(t_contract(VToken)22978)dyn_storage" + "type": "t_array(t_contract(VToken)23491)dyn_storage" }, { - "astId": 2458, + "astId": 2577, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusRate", "offset": 0, @@ -1938,7 +1938,7 @@ "type": "t_uint256" }, { - "astId": 2462, + "astId": 2581, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusSpeeds", "offset": 0, @@ -1946,23 +1946,23 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2466, + "astId": 2585, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusSupplyState", "offset": 0, "slot": "16", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)" }, { - "astId": 2470, + "astId": 2589, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusBorrowState", "offset": 0, "slot": "17", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)" }, { - "astId": 2476, + "astId": 2595, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusSupplierIndex", "offset": 0, @@ -1970,7 +1970,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2482, + "astId": 2601, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusBorrowerIndex", "offset": 0, @@ -1978,7 +1978,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2486, + "astId": 2605, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusAccrued", "offset": 0, @@ -1986,15 +1986,15 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2488, + "astId": 2607, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "vaiController", "offset": 0, "slot": "21", - "type": "t_contract(VAIControllerInterface)15527" + "type": "t_contract(VAIControllerInterface)15651" }, { - "astId": 2492, + "astId": 2611, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "mintedVAIs", "offset": 0, @@ -2002,7 +2002,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2494, + "astId": 2613, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "vaiMintRate", "offset": 0, @@ -2010,7 +2010,7 @@ "type": "t_uint256" }, { - "astId": 2496, + "astId": 2615, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "mintVAIGuardianPaused", "offset": 0, @@ -2018,7 +2018,7 @@ "type": "t_bool" }, { - "astId": 2498, + "astId": 2617, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "repayVAIGuardianPaused", "offset": 1, @@ -2026,7 +2026,7 @@ "type": "t_bool" }, { - "astId": 2500, + "astId": 2619, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "protocolPaused", "offset": 2, @@ -2034,7 +2034,7 @@ "type": "t_bool" }, { - "astId": 2502, + "astId": 2621, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusVAIRate", "offset": 0, @@ -2042,7 +2042,7 @@ "type": "t_uint256" }, { - "astId": 2507, + "astId": 2626, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusVAIVaultRate", "offset": 0, @@ -2050,7 +2050,7 @@ "type": "t_uint256" }, { - "astId": 2509, + "astId": 2628, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "vaiVaultAddress", "offset": 0, @@ -2058,7 +2058,7 @@ "type": "t_address" }, { - "astId": 2511, + "astId": 2630, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "releaseStartBlock", "offset": 0, @@ -2066,7 +2066,7 @@ "type": "t_uint256" }, { - "astId": 2513, + "astId": 2632, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "minReleaseAmount", "offset": 0, @@ -2074,7 +2074,7 @@ "type": "t_uint256" }, { - "astId": 2518, + "astId": 2637, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "borrowCapGuardian", "offset": 0, @@ -2082,7 +2082,7 @@ "type": "t_address" }, { - "astId": 2522, + "astId": 2641, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "borrowCaps", "offset": 0, @@ -2090,7 +2090,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2527, + "astId": 2646, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "treasuryGuardian", "offset": 0, @@ -2098,7 +2098,7 @@ "type": "t_address" }, { - "astId": 2529, + "astId": 2648, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "treasuryAddress", "offset": 0, @@ -2106,7 +2106,7 @@ "type": "t_address" }, { - "astId": 2531, + "astId": 2650, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "treasuryPercent", "offset": 0, @@ -2114,7 +2114,7 @@ "type": "t_uint256" }, { - "astId": 2538, + "astId": 2657, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusContributorSpeeds", "offset": 0, @@ -2122,7 +2122,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2542, + "astId": 2661, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "lastContributorBlock", "offset": 0, @@ -2130,7 +2130,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2547, + "astId": 2666, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "liquidatorContract", "offset": 0, @@ -2138,15 +2138,15 @@ "type": "t_address" }, { - "astId": 2552, + "astId": 2671, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "comptrollerLens", "offset": 0, "slot": "38", - "type": "t_contract(ComptrollerLensInterface)2366" + "type": "t_contract(ComptrollerLensInterface)2485" }, { - "astId": 2559, + "astId": 2678, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "supplyCaps", "offset": 0, @@ -2154,7 +2154,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2564, + "astId": 2683, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "accessControl", "offset": 0, @@ -2162,7 +2162,7 @@ "type": "t_address" }, { - "astId": 2570, + "astId": 2689, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_actionPaused", "offset": 0, @@ -2170,7 +2170,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" }, { - "astId": 2577, + "astId": 2696, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusBorrowSpeeds", "offset": 0, @@ -2178,7 +2178,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2581, + "astId": 2700, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "venusSupplySpeeds", "offset": 0, @@ -2186,7 +2186,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2590, + "astId": 2709, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "approvedDelegates", "offset": 0, @@ -2194,7 +2194,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2597, + "astId": 2716, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "isForcedLiquidationEnabled", "offset": 0, @@ -2202,23 +2202,23 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2615, + "astId": 2734, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_selectorToFacetAndPosition", "offset": 0, "slot": "46", - "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2605_storage)" + "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2724_storage)" }, { - "astId": 2619, + "astId": 2738, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_facetFunctionSelectors", "offset": 0, "slot": "47", - "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2611_storage)" + "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2730_storage)" }, { - "astId": 2622, + "astId": 2741, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "_facetAddresses", "offset": 0, @@ -2226,15 +2226,15 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 2627, + "astId": 2746, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "prime", "offset": 0, "slot": "49", - "type": "t_contract(IPrime)12228" + "type": "t_contract(IPrime)12530" }, { - "astId": 2636, + "astId": 2755, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "isForcedLiquidationEnabledForUser", "offset": 0, @@ -2242,7 +2242,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2641, + "astId": 2760, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "xvs", "offset": 0, @@ -2250,7 +2250,7 @@ "type": "t_address" }, { - "astId": 2643, + "astId": 2762, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "xvsVToken", "offset": 0, @@ -2276,8 +2276,8 @@ "label": "bytes4[]", "numberOfBytes": "32" }, - "t_array(t_contract(VToken)22978)dyn_storage": { - "base": "t_contract(VToken)22978", + "t_array(t_contract(VToken)23491)dyn_storage": { + "base": "t_contract(VToken)23491", "encoding": "dynamic_array", "label": "contract VToken[]", "numberOfBytes": "32" @@ -2292,37 +2292,37 @@ "label": "bytes4", "numberOfBytes": "4" }, - "t_contract(ComptrollerLensInterface)2366": { + "t_contract(ComptrollerLensInterface)2485": { "encoding": "inplace", "label": "contract ComptrollerLensInterface", "numberOfBytes": "20" }, - "t_contract(IPrime)12228": { + "t_contract(IPrime)12530": { "encoding": "inplace", "label": "contract IPrime", "numberOfBytes": "20" }, - "t_contract(PriceOracle)12051": { + "t_contract(PriceOracle)12353": { "encoding": "inplace", "label": "contract PriceOracle", "numberOfBytes": "20" }, - "t_contract(VAIControllerInterface)15527": { + "t_contract(VAIControllerInterface)15651": { "encoding": "inplace", "label": "contract VAIControllerInterface", "numberOfBytes": "20" }, - "t_contract(VToken)22978": { + "t_contract(VToken)23491": { "encoding": "inplace", "label": "contract VToken", "numberOfBytes": "20" }, - "t_mapping(t_address,t_array(t_contract(VToken)22978)dyn_storage)": { + "t_mapping(t_address,t_array(t_contract(VToken)23491)dyn_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => contract VToken[])", "numberOfBytes": "32", - "value": "t_array(t_contract(VToken)22978)dyn_storage" + "value": "t_array(t_contract(VToken)23491)dyn_storage" }, "t_mapping(t_address,t_bool)": { "encoding": "mapping", @@ -2352,26 +2352,26 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_bool)" }, - "t_mapping(t_address,t_struct(FacetFunctionSelectors)2611_storage)": { + "t_mapping(t_address,t_struct(FacetFunctionSelectors)2730_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV13Storage.FacetFunctionSelectors)", "numberOfBytes": "32", - "value": "t_struct(FacetFunctionSelectors)2611_storage" + "value": "t_struct(FacetFunctionSelectors)2730_storage" }, - "t_mapping(t_address,t_struct(Market)2426_storage)": { + "t_mapping(t_address,t_struct(Market)2545_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.Market)", "numberOfBytes": "32", - "value": "t_struct(Market)2426_storage" + "value": "t_struct(Market)2545_storage" }, - "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)": { + "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.VenusMarketState)", "numberOfBytes": "32", - "value": "t_struct(VenusMarketState)2453_storage" + "value": "t_struct(VenusMarketState)2572_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -2380,12 +2380,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2605_storage)": { + "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2724_storage)": { "encoding": "mapping", "key": "t_bytes4", "label": "mapping(bytes4 => struct ComptrollerV13Storage.FacetAddressAndPosition)", "numberOfBytes": "32", - "value": "t_struct(FacetAddressAndPosition)2605_storage" + "value": "t_struct(FacetAddressAndPosition)2724_storage" }, "t_mapping(t_uint256,t_bool)": { "encoding": "mapping", @@ -2394,12 +2394,12 @@ "numberOfBytes": "32", "value": "t_bool" }, - "t_struct(FacetAddressAndPosition)2605_storage": { + "t_struct(FacetAddressAndPosition)2724_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetAddressAndPosition", "members": [ { - "astId": 2602, + "astId": 2721, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "facetAddress", "offset": 0, @@ -2407,7 +2407,7 @@ "type": "t_address" }, { - "astId": 2604, + "astId": 2723, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "functionSelectorPosition", "offset": 20, @@ -2417,12 +2417,12 @@ ], "numberOfBytes": "32" }, - "t_struct(FacetFunctionSelectors)2611_storage": { + "t_struct(FacetFunctionSelectors)2730_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetFunctionSelectors", "members": [ { - "astId": 2608, + "astId": 2727, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "functionSelectors", "offset": 0, @@ -2430,7 +2430,7 @@ "type": "t_array(t_bytes4)dyn_storage" }, { - "astId": 2610, + "astId": 2729, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "facetAddressPosition", "offset": 0, @@ -2440,12 +2440,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Market)2426_storage": { + "t_struct(Market)2545_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.Market", "members": [ { - "astId": 2417, + "astId": 2536, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "isListed", "offset": 0, @@ -2453,7 +2453,7 @@ "type": "t_bool" }, { - "astId": 2419, + "astId": 2538, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "collateralFactorMantissa", "offset": 0, @@ -2461,7 +2461,7 @@ "type": "t_uint256" }, { - "astId": 2423, + "astId": 2542, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "accountMembership", "offset": 0, @@ -2469,7 +2469,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2425, + "astId": 2544, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "isVenus", "offset": 0, @@ -2479,12 +2479,12 @@ ], "numberOfBytes": "128" }, - "t_struct(VenusMarketState)2453_storage": { + "t_struct(VenusMarketState)2572_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.VenusMarketState", "members": [ { - "astId": 2450, + "astId": 2569, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "index", "offset": 0, @@ -2492,7 +2492,7 @@ "type": "t_uint224" }, { - "astId": 2452, + "astId": 2571, "contract": "contracts/Comptroller/Diamond/facets/PolicyFacet.sol:PolicyFacet", "label": "block", "offset": 28, diff --git a/deployments/bsctestnet/SetterFacet.json b/deployments/bsctestnet/SetterFacet.json index 9b154506e..d797086d4 100644 --- a/deployments/bsctestnet/SetterFacet.json +++ b/deployments/bsctestnet/SetterFacet.json @@ -1,5 +1,5 @@ { - "address": "0xaBdE9599a4aEcE4fEC59fBF2b8445149bc8B2c70", + "address": "0x490DFD07f592452307817C4283866035BDb3b275", "abi": [ { "anonymous": false, @@ -1833,28 +1833,28 @@ "type": "function" } ], - "transactionHash": "0xdd8c338e796fbd446f774345cdc681b03f79ed1d8fa60c27c683f5d8299095b8", + "transactionHash": "0xc9cf859dc1bd95052966582f65a84bbcaec51f1ff3165d89f0be34fba0ec4a24", "receipt": { "to": null, - "from": "0x7Bf1Fe2C42E79dbA813Bf5026B7720935a55ec5f", - "contractAddress": "0xaBdE9599a4aEcE4fEC59fBF2b8445149bc8B2c70", - "transactionIndex": 1, + "from": "0x464779C41C5f1Be598853C1F87bCC7087Ea75f28", + "contractAddress": "0x490DFD07f592452307817C4283866035BDb3b275", + "transactionIndex": 5, "gasUsed": "2759641", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x101ceceae6d24188e1eca1764fc2539155d4ad16247fd6bd35c9c87a54d07236", - "transactionHash": "0xdd8c338e796fbd446f774345cdc681b03f79ed1d8fa60c27c683f5d8299095b8", + "blockHash": "0xd8772533ca297176c9fd530d7e10eff5860ea77fc7ab9e67dfbbefed6a714d24", + "transactionHash": "0xc9cf859dc1bd95052966582f65a84bbcaec51f1ff3165d89f0be34fba0ec4a24", "logs": [], - "blockNumber": 38504171, - "cumulativeGasUsed": "2783278", + "blockNumber": 40555527, + "cumulativeGasUsed": "6989897", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "506bbeed5e5814c0309e06940945462d", - "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"pauseState\",\"type\":\"bool\"}],\"name\":\"ActionPausedMarket\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"ActionProtocolPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"IsForcedLiquidationEnabledForUserUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"IsForcedLiquidationEnabledUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlAddress\",\"type\":\"address\"}],\"name\":\"NewAccessControl\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBorrowCap\",\"type\":\"uint256\"}],\"name\":\"NewBorrowCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCloseFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCloseFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCollateralFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCollateralFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldComptrollerLens\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newComptrollerLens\",\"type\":\"address\"}],\"name\":\"NewComptrollerLens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":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\":\"address\",\"name\":\"oldLiquidatorContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLiquidatorContract\",\"type\":\"address\"}],\"name\":\"NewLiquidatorContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldPauseGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPauseGuardian\",\"type\":\"address\"}],\"name\":\"NewPauseGuardian\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract PriceOracle\",\"name\":\"oldPriceOracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract PriceOracle\",\"name\":\"newPriceOracle\",\"type\":\"address\"}],\"name\":\"NewPriceOracle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IPrime\",\"name\":\"oldPrimeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IPrime\",\"name\":\"newPrimeToken\",\"type\":\"address\"}],\"name\":\"NewPrimeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSupplyCap\",\"type\":\"uint256\"}],\"name\":\"NewSupplyCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldTreasuryAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTreasuryAddress\",\"type\":\"address\"}],\"name\":\"NewTreasuryAddress\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldTreasuryGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTreasuryGuardian\",\"type\":\"address\"}],\"name\":\"NewTreasuryGuardian\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldTreasuryPercent\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newTreasuryPercent\",\"type\":\"uint256\"}],\"name\":\"NewTreasuryPercent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VAIControllerInterface\",\"name\":\"oldVAIController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract VAIControllerInterface\",\"name\":\"newVAIController\",\"type\":\"address\"}],\"name\":\"NewVAIController\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVAIMintRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVAIMintRate\",\"type\":\"uint256\"}],\"name\":\"NewVAIMintRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"releaseStartBlock_\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"releaseInterval_\",\"type\":\"uint256\"}],\"name\":\"NewVAIVaultInfo\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVenusVAIVaultRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVenusVAIVaultRate\",\"type\":\"uint256\"}],\"name\":\"NewVenusVAIVaultRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldXVS\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newXVS\",\"type\":\"address\"}],\"name\":\"NewXVSToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldXVSVToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newXVSVToken\",\"type\":\"address\"}],\"name\":\"NewXVSVToken\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAccessControlAddress\",\"type\":\"address\"}],\"name\":\"_setAccessControl\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"markets_\",\"type\":\"address[]\"},{\"internalType\":\"enum ComptrollerTypes.Action[]\",\"name\":\"actions_\",\"type\":\"uint8[]\"},{\"internalType\":\"bool\",\"name\":\"paused_\",\"type\":\"bool\"}],\"name\":\"_setActionsPaused\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"_setCloseFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"_setCollateralFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"comptrollerLens_\",\"type\":\"address\"}],\"name\":\"_setComptrollerLens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"_setForcedLiquidation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"_setForcedLiquidationForUser\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"_setLiquidationIncentive\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newLiquidatorContract_\",\"type\":\"address\"}],\"name\":\"_setLiquidatorContract\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newBorrowCaps\",\"type\":\"uint256[]\"}],\"name\":\"_setMarketBorrowCaps\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newSupplyCaps\",\"type\":\"uint256[]\"}],\"name\":\"_setMarketSupplyCaps\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPauseGuardian\",\"type\":\"address\"}],\"name\":\"_setPauseGuardian\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"_setPriceOracle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"_prime\",\"type\":\"address\"}],\"name\":\"_setPrimeToken\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"_setProtocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newTreasuryGuardian\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newTreasuryAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newTreasuryPercent\",\"type\":\"uint256\"}],\"name\":\"_setTreasuryData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"vaiController_\",\"type\":\"address\"}],\"name\":\"_setVAIController\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newVAIMintRate\",\"type\":\"uint256\"}],\"name\":\"_setVAIMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"releaseStartBlock_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minReleaseAmount_\",\"type\":\"uint256\"}],\"name\":\"_setVAIVaultInfo\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"venusVAIVaultRate_\",\"type\":\"uint256\"}],\"name\":\"_setVenusVAIVaultRate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"xvs_\",\"type\":\"address\"}],\"name\":\"_setXVSToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"xvsVToken_\",\"type\":\"address\"}],\"name\":\"_setXVSVToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setMintedVAIOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the setters for the states\",\"methods\":{\"_setAccessControl(address)\":{\"details\":\"Allows the contract admin to set the address of access control of this contract\",\"params\":{\"newAccessControlAddress\":\"New address for the access control\"},\"return\":\"uint256 0=success, otherwise will revert\"},\"_setActionsPaused(address[],uint8[],bool)\":{\"details\":\"Allows a privileged role to pause/unpause the protocol action state\",\"params\":{\"actions_\":\"List of action ids to pause/unpause\",\"markets_\":\"Markets to pause/unpause the actions on\",\"paused_\":\"The new paused state (true=paused, false=unpaused)\"}},\"_setCloseFactor(uint256)\":{\"details\":\"Allows the contract admin to set the closeFactor used to liquidate borrows\",\"params\":{\"newCloseFactorMantissa\":\"New close factor, scaled by 1e18\"},\"return\":\"uint256 0=success, otherwise will revert\"},\"_setCollateralFactor(address,uint256)\":{\"details\":\"Allows a privileged role to set the collateralFactorMantissa\",\"params\":{\"newCollateralFactorMantissa\":\"The new collateral factor, scaled by 1e18\",\"vToken\":\"The market to set the factor on\"},\"return\":\"uint256 0=success, otherwise a failure. (See ErrorReporter for details)\"},\"_setComptrollerLens(address)\":{\"details\":\"Set ComptrollerLens contract address\",\"params\":{\"comptrollerLens_\":\"The new ComptrollerLens contract address to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setForcedLiquidation(address,bool)\":{\"details\":\"Allows a privileged role to set enable/disable forced liquidations\",\"params\":{\"enable\":\"Whether to enable forced liquidations\",\"vTokenBorrowed\":\"Borrowed vToken\"}},\"_setForcedLiquidationForUser(address,address,bool)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"enable\":\"Whether to enable forced liquidations\",\"vTokenBorrowed\":\"Borrowed vToken\"}},\"_setLiquidationIncentive(uint256)\":{\"details\":\"Allows a privileged role to set the liquidationIncentiveMantissa\",\"params\":{\"newLiquidationIncentiveMantissa\":\"New liquidationIncentive scaled by 1e18\"},\"return\":\"uint256 0=success, otherwise a failure. (See ErrorReporter for details)\"},\"_setLiquidatorContract(address)\":{\"details\":\"Allows the contract admin to update the address of liquidator contract\",\"params\":{\"newLiquidatorContract_\":\"The new address of the liquidator contract\"}},\"_setMarketBorrowCaps(address[],uint256[])\":{\"details\":\"Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to unlimited borrowing\",\"params\":{\"newBorrowCaps\":\"The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing\",\"vTokens\":\"The addresses of the markets (tokens) to change the borrow caps for\"}},\"_setMarketSupplyCaps(address[],uint256[])\":{\"details\":\"Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\",\"params\":{\"newSupplyCaps\":\"The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\",\"vTokens\":\"The addresses of the markets (tokens) to change the supply caps for\"}},\"_setPauseGuardian(address)\":{\"details\":\"Allows the contract admin to change the Pause Guardian\",\"params\":{\"newPauseGuardian\":\"The address of the new Pause Guardian\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"_setPriceOracle(address)\":{\"details\":\"Allows the contract admin to set a new price oracle used by the Comptroller\",\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setPrimeToken(address)\":{\"return\":\"uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setProtocolPaused(bool)\":{\"details\":\"Allows a privileged role to pause/unpause protocol\",\"params\":{\"state\":\"The new state (true=paused, false=unpaused)\"},\"return\":\"bool The updated state of the protocol\"},\"_setTreasuryData(address,address,uint256)\":{\"params\":{\"newTreasuryAddress\":\"The new address of the treasury to be set\",\"newTreasuryGuardian\":\"The new address of the treasury guardian to be set\",\"newTreasuryPercent\":\"The new treasury percent to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIController(address)\":{\"details\":\"Admin function to set a new VAI controller\",\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIMintRate(uint256)\":{\"params\":{\"newVAIMintRate\":\"The new VAI mint rate to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIVaultInfo(address,uint256,uint256)\":{\"params\":{\"minReleaseAmount_\":\"The minimum release amount to VAI Vault\",\"releaseStartBlock_\":\"The start block of release to VAI Vault\",\"vault_\":\"The address of the VAI Vault\"}},\"_setVenusVAIVaultRate(uint256)\":{\"params\":{\"venusVAIVaultRate_\":\"The amount of XVS wei per block to distribute to VAI Vault\"}},\"_setXVSToken(address)\":{\"params\":{\"xvs_\":\"The address of the XVS token\"}},\"_setXVSVToken(address)\":{\"params\":{\"xvsVToken_\":\"The address of the XVS vToken\"}},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"setMintedVAIOf(address,uint256)\":{\"params\":{\"amount\":\"The amount of VAI to set to the account\",\"owner\":\"The address of the account to set\"},\"return\":\"The number of minted VAI by `owner`\"}},\"title\":\"SetterFacet\"},\"userdoc\":{\"methods\":{\"_setAccessControl(address)\":{\"notice\":\"Sets the address of the access control of this contract\"},\"_setActionsPaused(address[],uint8[],bool)\":{\"notice\":\"Pause/unpause certain actions\"},\"_setCloseFactor(uint256)\":{\"notice\":\"Sets the closeFactor used when liquidating borrows\"},\"_setCollateralFactor(address,uint256)\":{\"notice\":\"Sets the collateralFactor for a market\"},\"_setForcedLiquidation(address,bool)\":{\"notice\":\"Enables forced liquidations for a market. If forced liquidation is enabled, borrows in the market may be liquidated regardless of the account liquidity\"},\"_setForcedLiquidationForUser(address,address,bool)\":{\"notice\":\"Enables forced liquidations for user's borrows in a certain market. If forced liquidation is enabled, user's borrows in the market may be liquidated regardless of the account liquidity. Forced liquidation may be enabled for a user even if it is not enabled for the entire market.\"},\"_setLiquidationIncentive(uint256)\":{\"notice\":\"Sets liquidationIncentive\"},\"_setLiquidatorContract(address)\":{\"notice\":\"Update the address of the liquidator contract\"},\"_setMarketBorrowCaps(address[],uint256[])\":{\"notice\":\"Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\"},\"_setMarketSupplyCaps(address[],uint256[])\":{\"notice\":\"Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\"},\"_setPauseGuardian(address)\":{\"notice\":\"Admin function to change the Pause Guardian\"},\"_setPriceOracle(address)\":{\"notice\":\"Sets a new price oracle for the comptroller\"},\"_setPrimeToken(address)\":{\"notice\":\"Sets the prime token contract for the comptroller\"},\"_setProtocolPaused(bool)\":{\"notice\":\"Set whole protocol pause/unpause state\"},\"_setTreasuryData(address,address,uint256)\":{\"notice\":\"Set the treasury data.\"},\"_setVAIController(address)\":{\"notice\":\"Sets a new VAI controller\"},\"_setVAIMintRate(uint256)\":{\"notice\":\"Set the VAI mint rate\"},\"_setVAIVaultInfo(address,uint256,uint256)\":{\"notice\":\"Set the VAI Vault infos\"},\"_setVenusVAIVaultRate(uint256)\":{\"notice\":\"Set the amount of XVS distributed per block to VAI Vault\"},\"_setXVSToken(address)\":{\"notice\":\"Set the address of the XVS token\"},\"_setXVSVToken(address)\":{\"notice\":\"Set the address of the XVS vToken\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"setMintedVAIOf(address,uint256)\":{\"notice\":\"Set the minted VAI amount of the `owner`\"}},\"notice\":\"This facet contract contains all the configurational setter functions\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/SetterFacet.sol\":\"SetterFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0xab3aca949ad85c46d8b7866330594282136109adbdab301d447108a8551e3dc3\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which corresponds to unlimited borrowing.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x13aa5a019c0ea5149d00480b5a3e1281ec316f8d159c52705f45b4c75a5abcb8\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/SetterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { ISetterFacet } from \\\"../interfaces/ISetterFacet.sol\\\";\\nimport { PriceOracle } from \\\"../../../Oracle/PriceOracle.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"../../ComptrollerLensInterface.sol\\\";\\nimport { VAIControllerInterface } from \\\"../../../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\nimport { IPrime } from \\\"../../../Tokens/Prime/IPrime.sol\\\";\\n\\n/**\\n * @title SetterFacet\\n * @author Venus\\n * @dev This facet contains all the setters for the states\\n * @notice This facet contract contains all the configurational setter functions\\n */\\ncontract SetterFacet is ISetterFacet, FacetBase {\\n /// @notice Emitted when close factor is changed by admin\\n event NewCloseFactor(uint256 oldCloseFactorMantissa, uint256 newCloseFactorMantissa);\\n\\n /// @notice Emitted when a collateral factor is changed by admin\\n event NewCollateralFactor(\\n VToken indexed vToken,\\n uint256 oldCollateralFactorMantissa,\\n uint256 newCollateralFactorMantissa\\n );\\n\\n /// @notice Emitted when liquidation incentive is changed by admin\\n event NewLiquidationIncentive(uint256 oldLiquidationIncentiveMantissa, uint256 newLiquidationIncentiveMantissa);\\n\\n /// @notice Emitted when price oracle is changed\\n event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle);\\n\\n /// @notice Emitted when borrow cap for a vToken is changed\\n event NewBorrowCap(VToken indexed vToken, uint256 newBorrowCap);\\n\\n /// @notice Emitted when VAIController is changed\\n event NewVAIController(VAIControllerInterface oldVAIController, VAIControllerInterface newVAIController);\\n\\n /// @notice Emitted when VAI mint rate is changed by admin\\n event NewVAIMintRate(uint256 oldVAIMintRate, uint256 newVAIMintRate);\\n\\n /// @notice Emitted when protocol state is changed by admin\\n event ActionProtocolPaused(bool state);\\n\\n /// @notice Emitted when treasury guardian is changed\\n event NewTreasuryGuardian(address oldTreasuryGuardian, address newTreasuryGuardian);\\n\\n /// @notice Emitted when treasury address is changed\\n event NewTreasuryAddress(address oldTreasuryAddress, address newTreasuryAddress);\\n\\n /// @notice Emitted when treasury percent is changed\\n event NewTreasuryPercent(uint256 oldTreasuryPercent, uint256 newTreasuryPercent);\\n\\n /// @notice Emitted when liquidator adress is changed\\n event NewLiquidatorContract(address oldLiquidatorContract, address newLiquidatorContract);\\n\\n /// @notice Emitted when ComptrollerLens address is changed\\n event NewComptrollerLens(address oldComptrollerLens, address newComptrollerLens);\\n\\n /// @notice Emitted when supply cap for a vToken is changed\\n event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /// @notice Emitted when pause guardian is changed\\n event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken indexed vToken, Action indexed action, bool pauseState);\\n\\n /// @notice Emitted when VAI Vault info is changed\\n event NewVAIVaultInfo(address indexed vault_, uint256 releaseStartBlock_, uint256 releaseInterval_);\\n\\n /// @notice Emitted when Venus VAI Vault rate is changed\\n event NewVenusVAIVaultRate(uint256 oldVenusVAIVaultRate, uint256 newVenusVAIVaultRate);\\n\\n /// @notice Emitted when prime token contract address is changed\\n event NewPrimeToken(IPrime oldPrimeToken, IPrime newPrimeToken);\\n\\n /// @notice Emitted when forced liquidation is enabled or disabled for all users in a market\\n event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);\\n\\n /// @notice Emitted when forced liquidation is enabled or disabled for a user borrowing in a market\\n event IsForcedLiquidationEnabledForUserUpdated(address indexed borrower, address indexed vToken, bool enable);\\n\\n /// @notice Emitted when XVS token address is changed\\n event NewXVSToken(address indexed oldXVS, address indexed newXVS);\\n\\n /// @notice Emitted when XVS vToken address is changed\\n event NewXVSVToken(address indexed oldXVSVToken, address indexed newXVSVToken);\\n\\n /**\\n * @notice Compare two addresses to ensure they are different\\n * @param oldAddress The original address to compare\\n * @param newAddress The new address to compare\\n */\\n modifier compareAddress(address oldAddress, address newAddress) {\\n require(oldAddress != newAddress, \\\"old address is same as new address\\\");\\n _;\\n }\\n\\n /**\\n * @notice Compare two values to ensure they are different\\n * @param oldValue The original value to compare\\n * @param newValue The new value to compare\\n */\\n modifier compareValue(uint256 oldValue, uint256 newValue) {\\n require(oldValue != newValue, \\\"old value is same as new value\\\");\\n _;\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the comptroller\\n * @dev Allows the contract admin to set a new price oracle used by the Comptroller\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setPriceOracle(\\n PriceOracle newOracle\\n ) external compareAddress(address(oracle), address(newOracle)) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(address(newOracle));\\n\\n // Track the old oracle for the comptroller\\n PriceOracle oldOracle = oracle;\\n\\n // Set comptroller's oracle to newOracle\\n oracle = newOracle;\\n\\n // Emit NewPriceOracle(oldOracle, newOracle)\\n emit NewPriceOracle(oldOracle, newOracle);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the closeFactor used when liquidating borrows\\n * @dev Allows the contract admin to set the closeFactor used to liquidate borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @return uint256 0=success, otherwise will revert\\n */\\n function _setCloseFactor(\\n uint256 newCloseFactorMantissa\\n ) external compareValue(closeFactorMantissa, newCloseFactorMantissa) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n\\n Exp memory newCloseFactorExp = Exp({ mantissa: newCloseFactorMantissa });\\n\\n //-- Check close factor <= 0.9\\n Exp memory highLimit = Exp({ mantissa: closeFactorMaxMantissa });\\n //-- Check close factor >= 0.05\\n Exp memory lowLimit = Exp({ mantissa: closeFactorMinMantissa });\\n\\n if (lessThanExp(highLimit, newCloseFactorExp) || greaterThanExp(lowLimit, newCloseFactorExp)) {\\n return fail(Error.INVALID_CLOSE_FACTOR, FailureInfo.SET_CLOSE_FACTOR_VALIDATION);\\n }\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the address of the access control of this contract\\n * @dev Allows the contract admin to set the address of access control of this contract\\n * @param newAccessControlAddress New address for the access control\\n * @return uint256 0=success, otherwise will revert\\n */\\n function _setAccessControl(\\n address newAccessControlAddress\\n ) external compareAddress(accessControl, newAccessControlAddress) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(newAccessControlAddress);\\n\\n address oldAccessControlAddress = accessControl;\\n\\n accessControl = newAccessControlAddress;\\n emit NewAccessControl(oldAccessControlAddress, newAccessControlAddress);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev Allows a privileged role to set the collateralFactorMantissa\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\\n */\\n function _setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa\\n )\\n external\\n compareValue(markets[address(vToken)].collateralFactorMantissa, newCollateralFactorMantissa)\\n returns (uint256)\\n {\\n // Check caller is allowed by access control manager\\n ensureAllowed(\\\"_setCollateralFactor(address,uint256)\\\");\\n ensureNonzeroAddress(address(vToken));\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n ensureListed(market);\\n\\n Exp memory newCollateralFactorExp = Exp({ mantissa: newCollateralFactorMantissa });\\n\\n //-- Check collateral factor <= 0.9\\n Exp memory highLimit = Exp({ mantissa: collateralFactorMaxMantissa });\\n if (lessThanExp(highLimit, newCollateralFactorExp)) {\\n return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION);\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(vToken) == 0) {\\n return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE);\\n }\\n\\n // Set market's collateral factor to new collateral factor, remember old value\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n\\n // Emit event with asset, old collateral factor, and new collateral factor\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev Allows a privileged role to set the liquidationIncentiveMantissa\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\\n */\\n function _setLiquidationIncentive(\\n uint256 newLiquidationIncentiveMantissa\\n ) external compareValue(liquidationIncentiveMantissa, newLiquidationIncentiveMantissa) returns (uint256) {\\n ensureAllowed(\\\"_setLiquidationIncentive(uint256)\\\");\\n\\n require(newLiquidationIncentiveMantissa >= 1e18, \\\"incentive < 1e18\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n // Set liquidation incentive to new incentive\\n liquidationIncentiveMantissa = newLiquidationIncentiveMantissa;\\n\\n // Emit event with old incentive, new incentive\\n emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Update the address of the liquidator contract\\n * @dev Allows the contract admin to update the address of liquidator contract\\n * @param newLiquidatorContract_ The new address of the liquidator contract\\n */\\n function _setLiquidatorContract(\\n address newLiquidatorContract_\\n ) external compareAddress(liquidatorContract, newLiquidatorContract_) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(newLiquidatorContract_);\\n address oldLiquidatorContract = liquidatorContract;\\n liquidatorContract = newLiquidatorContract_;\\n emit NewLiquidatorContract(oldLiquidatorContract, newLiquidatorContract_);\\n }\\n\\n /**\\n * @notice Admin function to change the Pause Guardian\\n * @dev Allows the contract admin to change the Pause Guardian\\n * @param newPauseGuardian The address of the new Pause Guardian\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function _setPauseGuardian(\\n address newPauseGuardian\\n ) external compareAddress(pauseGuardian, newPauseGuardian) returns (uint256) {\\n ensureAdmin();\\n ensureNonzeroAddress(newPauseGuardian);\\n\\n // Save current value for inclusion in log\\n address oldPauseGuardian = pauseGuardian;\\n // Store pauseGuardian with value newPauseGuardian\\n pauseGuardian = newPauseGuardian;\\n\\n // Emit NewPauseGuardian(OldPauseGuardian, NewPauseGuardian)\\n emit NewPauseGuardian(oldPauseGuardian, newPauseGuardian);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\\n * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to unlimited borrowing\\n * @param vTokens The addresses of the markets (tokens) to change the borrow caps for\\n * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing\\n */\\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n ensureAllowed(\\\"_setMarketBorrowCaps(address[],uint256[])\\\");\\n\\n uint256 numMarkets = vTokens.length;\\n uint256 numBorrowCaps = newBorrowCaps.length;\\n\\n require(numMarkets != 0 && numMarkets == numBorrowCaps, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numMarkets; ++i) {\\n borrowCaps[address(vTokens[i])] = newBorrowCaps[i];\\n emit NewBorrowCap(vTokens[i], newBorrowCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\\n * @dev Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\\n * @param vTokens The addresses of the markets (tokens) to change the supply caps for\\n * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\\n */\\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n ensureAllowed(\\\"_setMarketSupplyCaps(address[],uint256[])\\\");\\n\\n uint256 numMarkets = vTokens.length;\\n uint256 numSupplyCaps = newSupplyCaps.length;\\n\\n require(numMarkets != 0 && numMarkets == numSupplyCaps, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numMarkets; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Set whole protocol pause/unpause state\\n * @dev Allows a privileged role to pause/unpause protocol\\n * @param state The new state (true=paused, false=unpaused)\\n * @return bool The updated state of the protocol\\n */\\n function _setProtocolPaused(bool state) external returns (bool) {\\n ensureAllowed(\\\"_setProtocolPaused(bool)\\\");\\n\\n protocolPaused = state;\\n emit ActionProtocolPaused(state);\\n return state;\\n }\\n\\n /**\\n * @notice Pause/unpause certain actions\\n * @dev Allows a privileged role to pause/unpause the protocol action state\\n * @param markets_ Markets to pause/unpause the actions on\\n * @param actions_ List of action ids to pause/unpause\\n * @param paused_ The new paused state (true=paused, false=unpaused)\\n */\\n function _setActionsPaused(address[] calldata markets_, Action[] calldata actions_, bool paused_) external {\\n ensureAllowed(\\\"_setActionsPaused(address[],uint8[],bool)\\\");\\n\\n uint256 numMarkets = markets_.length;\\n uint256 numActions = actions_.length;\\n for (uint256 marketIdx; marketIdx < numMarkets; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < numActions; ++actionIdx) {\\n setActionPausedInternal(markets_[marketIdx], actions_[actionIdx], paused_);\\n }\\n }\\n }\\n\\n /**\\n * @dev Pause/unpause an action on a market\\n * @param market Market to pause/unpause the action on\\n * @param action Action id to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n */\\n function setActionPausedInternal(address market, Action action, bool paused) internal {\\n ensureListed(markets[market]);\\n _actionPaused[market][uint256(action)] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @notice Sets a new VAI controller\\n * @dev Admin function to set a new VAI controller\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setVAIController(\\n VAIControllerInterface vaiController_\\n ) external compareAddress(address(vaiController), address(vaiController_)) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(address(vaiController_));\\n\\n VAIControllerInterface oldVaiController = vaiController;\\n vaiController = vaiController_;\\n emit NewVAIController(oldVaiController, vaiController_);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the VAI mint rate\\n * @param newVAIMintRate The new VAI mint rate to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setVAIMintRate(\\n uint256 newVAIMintRate\\n ) external compareValue(vaiMintRate, newVAIMintRate) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n uint256 oldVAIMintRate = vaiMintRate;\\n vaiMintRate = newVAIMintRate;\\n emit NewVAIMintRate(oldVAIMintRate, newVAIMintRate);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the minted VAI amount of the `owner`\\n * @param owner The address of the account to set\\n * @param amount The amount of VAI to set to the account\\n * @return The number of minted VAI by `owner`\\n */\\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256) {\\n checkProtocolPauseState();\\n\\n // Pausing is a very serious situation - we revert to sound the alarms\\n require(!mintVAIGuardianPaused && !repayVAIGuardianPaused, \\\"VAI is paused\\\");\\n // Check caller is vaiController\\n if (msg.sender != address(vaiController)) {\\n return fail(Error.REJECTION, FailureInfo.SET_MINTED_VAI_REJECTION);\\n }\\n mintedVAIs[owner] = amount;\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the treasury data.\\n * @param newTreasuryGuardian The new address of the treasury guardian to be set\\n * @param newTreasuryAddress The new address of the treasury to be set\\n * @param newTreasuryPercent The new treasury percent to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setTreasuryData(\\n address newTreasuryGuardian,\\n address newTreasuryAddress,\\n uint256 newTreasuryPercent\\n ) external returns (uint256) {\\n // Check caller is admin\\n ensureAdminOr(treasuryGuardian);\\n\\n require(newTreasuryPercent < 1e18, \\\"percent >= 100%\\\");\\n ensureNonzeroAddress(newTreasuryGuardian);\\n ensureNonzeroAddress(newTreasuryAddress);\\n\\n address oldTreasuryGuardian = treasuryGuardian;\\n address oldTreasuryAddress = treasuryAddress;\\n uint256 oldTreasuryPercent = treasuryPercent;\\n\\n treasuryGuardian = newTreasuryGuardian;\\n treasuryAddress = newTreasuryAddress;\\n treasuryPercent = newTreasuryPercent;\\n\\n emit NewTreasuryGuardian(oldTreasuryGuardian, newTreasuryGuardian);\\n emit NewTreasuryAddress(oldTreasuryAddress, newTreasuryAddress);\\n emit NewTreasuryPercent(oldTreasuryPercent, newTreasuryPercent);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /*** Venus Distribution ***/\\n\\n /**\\n * @dev Set ComptrollerLens contract address\\n * @param comptrollerLens_ The new ComptrollerLens contract address to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setComptrollerLens(\\n ComptrollerLensInterface comptrollerLens_\\n ) external compareAddress(address(comptrollerLens), address(comptrollerLens_)) returns (uint256) {\\n ensureAdmin();\\n ensureNonzeroAddress(address(comptrollerLens_));\\n address oldComptrollerLens = address(comptrollerLens);\\n comptrollerLens = comptrollerLens_;\\n emit NewComptrollerLens(oldComptrollerLens, address(comptrollerLens));\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the amount of XVS distributed per block to VAI Vault\\n * @param venusVAIVaultRate_ The amount of XVS wei per block to distribute to VAI Vault\\n */\\n function _setVenusVAIVaultRate(\\n uint256 venusVAIVaultRate_\\n ) external compareValue(venusVAIVaultRate, venusVAIVaultRate_) {\\n ensureAdmin();\\n if (vaiVaultAddress != address(0)) {\\n releaseToVault();\\n }\\n uint256 oldVenusVAIVaultRate = venusVAIVaultRate;\\n venusVAIVaultRate = venusVAIVaultRate_;\\n emit NewVenusVAIVaultRate(oldVenusVAIVaultRate, venusVAIVaultRate_);\\n }\\n\\n /**\\n * @notice Set the VAI Vault infos\\n * @param vault_ The address of the VAI Vault\\n * @param releaseStartBlock_ The start block of release to VAI Vault\\n * @param minReleaseAmount_ The minimum release amount to VAI Vault\\n */\\n function _setVAIVaultInfo(\\n address vault_,\\n uint256 releaseStartBlock_,\\n uint256 minReleaseAmount_\\n ) external compareAddress(vaiVaultAddress, vault_) {\\n ensureAdmin();\\n ensureNonzeroAddress(vault_);\\n if (vaiVaultAddress != address(0)) {\\n releaseToVault();\\n }\\n\\n vaiVaultAddress = vault_;\\n releaseStartBlock = releaseStartBlock_;\\n minReleaseAmount = minReleaseAmount_;\\n emit NewVAIVaultInfo(vault_, releaseStartBlock_, minReleaseAmount_);\\n }\\n\\n /**\\n * @notice Sets the prime token contract for the comptroller\\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setPrimeToken(IPrime _prime) external returns (uint) {\\n ensureAdmin();\\n ensureNonzeroAddress(address(_prime));\\n\\n IPrime oldPrime = prime;\\n prime = _prime;\\n emit NewPrimeToken(oldPrime, _prime);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /** @notice Enables forced liquidations for a market. If forced liquidation is enabled,\\n * borrows in the market may be liquidated regardless of the account liquidity\\n * @dev Allows a privileged role to set enable/disable forced liquidations\\n * @param vTokenBorrowed Borrowed vToken\\n * @param enable Whether to enable forced liquidations\\n */\\n function _setForcedLiquidation(address vTokenBorrowed, bool enable) external {\\n ensureAllowed(\\\"_setForcedLiquidation(address,bool)\\\");\\n if (vTokenBorrowed != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n isForcedLiquidationEnabled[vTokenBorrowed] = enable;\\n emit IsForcedLiquidationEnabledUpdated(vTokenBorrowed, enable);\\n }\\n\\n /**\\n * @notice Enables forced liquidations for user's borrows in a certain market. If forced\\n * liquidation is enabled, user's borrows in the market may be liquidated regardless of\\n * the account liquidity. Forced liquidation may be enabled for a user even if it is not\\n * enabled for the entire market.\\n * @param borrower The address of the borrower\\n * @param vTokenBorrowed Borrowed vToken\\n * @param enable Whether to enable forced liquidations\\n */\\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external {\\n ensureAllowed(\\\"_setForcedLiquidationForUser(address,address,bool)\\\");\\n if (vTokenBorrowed != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed] = enable;\\n emit IsForcedLiquidationEnabledForUserUpdated(borrower, vTokenBorrowed, enable);\\n }\\n\\n /**\\n * @notice Set the address of the XVS token\\n * @param xvs_ The address of the XVS token\\n */\\n function _setXVSToken(address xvs_) external {\\n ensureAdmin();\\n ensureNonzeroAddress(xvs_);\\n\\n emit NewXVSToken(xvs, xvs_);\\n xvs = xvs_;\\n }\\n\\n /**\\n * @notice Set the address of the XVS vToken\\n * @param xvsVToken_ The address of the XVS vToken\\n */\\n function _setXVSVToken(address xvsVToken_) external {\\n ensureAdmin();\\n ensureNonzeroAddress(xvsVToken_);\\n\\n address underlying = VToken(xvsVToken_).underlying();\\n require(underlying == xvs, \\\"invalid xvs vtoken address\\\");\\n\\n emit NewXVSVToken(xvsVToken, xvsVToken_);\\n xvsVToken = xvsVToken_;\\n }\\n}\\n\",\"keccak256\":\"0x54e751d7dfd92147b1793379714f893759346f8ece01a03d91b1990fae1470b0\"},\"contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { PriceOracle } from \\\"../../../Oracle/PriceOracle.sol\\\";\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { ComptrollerTypes } from \\\"../../ComptrollerStorage.sol\\\";\\nimport { VAIControllerInterface } from \\\"../../../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"../../../Comptroller/ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../../../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ISetterFacet {\\n function _setPriceOracle(PriceOracle newOracle) external returns (uint256);\\n\\n function _setCloseFactor(uint256 newCloseFactorMantissa) external returns (uint256);\\n\\n function _setAccessControl(address newAccessControlAddress) external returns (uint256);\\n\\n function _setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256);\\n\\n function _setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256);\\n\\n function _setLiquidatorContract(address newLiquidatorContract_) external;\\n\\n function _setPauseGuardian(address newPauseGuardian) external returns (uint256);\\n\\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external;\\n\\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external;\\n\\n function _setProtocolPaused(bool state) external returns (bool);\\n\\n function _setActionsPaused(\\n address[] calldata markets,\\n ComptrollerTypes.Action[] calldata actions,\\n bool paused\\n ) external;\\n\\n function _setVAIController(VAIControllerInterface vaiController_) external returns (uint256);\\n\\n function _setVAIMintRate(uint256 newVAIMintRate) external returns (uint256);\\n\\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256);\\n\\n function _setTreasuryData(\\n address newTreasuryGuardian,\\n address newTreasuryAddress,\\n uint256 newTreasuryPercent\\n ) external returns (uint256);\\n\\n function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint256);\\n\\n function _setVenusVAIVaultRate(uint256 venusVAIVaultRate_) external;\\n\\n function _setVAIVaultInfo(address vault_, uint256 releaseStartBlock_, uint256 minReleaseAmount_) external;\\n\\n function _setForcedLiquidation(address vToken, bool enable) external;\\n\\n function _setPrimeToken(IPrime _prime) external returns (uint);\\n\\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external;\\n\\n function _setXVSToken(address xvs_) external;\\n\\n function _setXVSVToken(address xvsVToken_) external;\\n}\\n\",\"keccak256\":\"0x8d1e48445f80aca8652555a50783e3fb908351040abf45a90f1ce557abcabede\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function getVAIAddress() public view returns (address);\\n\\n function getMintableVAI(address minter) public view returns (uint, uint);\\n\\n function mintVAI(address minter, uint mintVAIAmount) external returns (uint);\\n\\n function repayVAI(address repayer, uint repayVAIAmount) external returns (uint);\\n\\n function liquidateVAI(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint, uint);\\n\\n function _initializeVenusVAIState(uint blockNumber) external returns (uint);\\n\\n function updateVenusVAIMintIndex() external returns (uint);\\n\\n function calcDistributeVAIMinterVenus(address vaiMinter) external returns (uint, uint, uint, uint);\\n\\n function getVAIRepayAmount(address account) public view returns (uint);\\n}\\n\",\"keccak256\":\"0x17eb6edb1262c4effcad86f614ff20d00256278485054b11aa5cf011ff6f8a86\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0xc77c4dd91f93f778c5048fa0e68cc0cad2fd4a308add54f0172c507858ce06c8\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506130ee806100206000396000f3fe608060405234801561001057600080fd5b50600436106103f15760003560e01c80637dc0d1d011610215578063bf32442d11610125578063e37d4b79116100b8578063f445d70311610087578063f445d70314610cdf578063f519fc3014610d0d578063f851a44014610d33578063fa6331d814610d3b578063fd51a3ad14610d43576103f1565b8063e37d4b7914610c56578063e4028eee14610c7c578063e85a296014610ca8578063e875544614610cd7576103f1565b8063d24febad116100f4578063d24febad14610be4578063d3270f9914610c1a578063dce1544914610c22578063dcfbc0c714610c4e576103f1565b8063bf32442d14610ba8578063c5b4db5514610bb0578063c5f956af14610bd4578063c7ee005e14610bdc576103f1565b80639bb27d62116101a8578063b8324c7c11610177578063b8324c7c14610afe578063bb82aa5e14610b4c578063bb85745014610b54578063bbb8864a14610b7a578063bec04f7214610ba0576103f1565b80639bb27d6214610aa25780639bf34cbb14610aaa5780639cfdd9e614610ad0578063b2eafc3914610af6576103f1565b8063919a3736116101e4578063919a373614610a465780639254f5e514610a6c5780639460c8b514610a7457806394b2294b14610a9a576103f1565b80637dc0d1d0146109aa5780638a7dc165146109b25780638c1ac18a146109d85780638e8f294b146109fe576103f1565b8063425fad581161031057806352d84d1e116102a3578063607ef6c111610272578063607ef6c1146108b75780636662c7c914610975578063719f701b14610992578063765513831461099a5780637d172bd5146109a2576103f1565b806352d84d1e1461082857806355ee1fe1146108455780635dd3fc9d1461086b5780635f5af1aa14610891576103f1565b80634ef233fc116102df5780634ef233fc146106f95780634fd42e171461071f57806351a485e41461073c578063522c656b146107fa576103f1565b8063425fad58146106915780634a584432146106995780634ada90af146106bf5780634e0853db146106c7576103f1565b806326782247116103885780632ec04124116103575780632ec0412414610621578063317b0b771461063e5780634088c73e1461065b57806341a18d2c14610663576103f1565b806326782247146105145780632a6a60651461051c5780632b5d790c1461053b5780632bc7e29e146105fb576103f1565b806310b98338116103c457806310b983381461046c57806317db2163146104ae57806321af4569146104e857806324a3d6221461050c576103f1565b806302c3bcbb146103f657806304ef9d581461042e57806308e0225c146104365780630db4b4e514610464575b600080fd5b61041c6004803603602081101561040c57600080fd5b50356001600160a01b0316610d6f565b60408051918252519081900360200190f35b61041c610d81565b61041c6004803603604081101561044c57600080fd5b506001600160a01b0381358116916020013516610d87565b61041c610da4565b61049a6004803603604081101561048257600080fd5b506001600160a01b0381358116916020013516610daa565b604080519115158252519081900360200190f35b6104e6600480360360608110156104c457600080fd5b506001600160a01b038135811691602081013590911690604001351515610dca565b005b6104f0610e8f565b604080516001600160a01b039092168252519081900360200190f35b6104f0610e9e565b6104f0610ead565b61049a6004803603602081101561053257600080fd5b50351515610ebc565b6104e66004803603606081101561055157600080fd5b810190602081018135600160201b81111561056b57600080fd5b82018360208201111561057d57600080fd5b803590602001918460208302840111600160201b8311171561059e57600080fd5b919390929091602081019035600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460208302840111600160201b831117156105ee57600080fd5b9193509150351515610f4e565b61041c6004803603602081101561061157600080fd5b50356001600160a01b0316610fea565b61041c6004803603602081101561063757600080fd5b5035610ffc565b61041c6004803603602081101561065457600080fd5b503561109e565b61049a6111c8565b61041c6004803603604081101561067957600080fd5b506001600160a01b03813581169160200135166111d1565b61049a6111ee565b61041c600480360360208110156106af57600080fd5b50356001600160a01b03166111fd565b61041c61120f565b6104e6600480360360608110156106dd57600080fd5b506001600160a01b038135169060208101359060400135611215565b6104e66004803603602081101561070f57600080fd5b50356001600160a01b03166112fa565b61041c6004803603602081101561073557600080fd5b5035611434565b6104e66004803603604081101561075257600080fd5b810190602081018135600160201b81111561076c57600080fd5b82018360208201111561077e57600080fd5b803590602001918460208302840111600160201b8311171561079f57600080fd5b919390929091602081019035600160201b8111156107bc57600080fd5b8201836020820111156107ce57600080fd5b803590602001918460208302840111600160201b831117156107ef57600080fd5b509092509050611538565b6104e66004803603604081101561081057600080fd5b506001600160a01b038135169060200135151561168b565b6104f06004803603602081101561083e57600080fd5b5035611742565b61041c6004803603602081101561085b57600080fd5b50356001600160a01b0316611769565b61041c6004803603602081101561088157600080fd5b50356001600160a01b0316611834565b61041c600480360360208110156108a757600080fd5b50356001600160a01b0316611846565b6104e6600480360360408110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460208302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460208302840111600160201b8311171561096a57600080fd5b509092509050611911565b6104e66004803603602081101561098b57600080fd5b5035611a5b565b61041c611b0c565b61049a611b12565b6104f0611b20565b6104f0611b2f565b61041c600480360360208110156109c857600080fd5b50356001600160a01b0316611b3e565b61049a600480360360208110156109ee57600080fd5b50356001600160a01b0316611b50565b610a2460048036036020811015610a1457600080fd5b50356001600160a01b0316611b65565b6040805193151584526020840192909252151582820152519081900360600190f35b6104e660048036036020811015610a5c57600080fd5b50356001600160a01b0316611b8b565b6104f0611bf8565b61041c60048036036020811015610a8a57600080fd5b50356001600160a01b0316611c07565b61041c611c82565b6104f0611c88565b61041c60048036036020811015610ac057600080fd5b50356001600160a01b0316611c97565b61041c60048036036020811015610ae657600080fd5b50356001600160a01b0316611d61565b6104f0611e2c565b610b2460048036036020811015610b1457600080fd5b50356001600160a01b0316611e3b565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104f0611e65565b6104e660048036036020811015610b6a57600080fd5b50356001600160a01b0316611e74565b61041c60048036036020811015610b9057600080fd5b50356001600160a01b0316611f3b565b61041c611f4d565b6104f0611f53565b610bb8611f62565b604080516001600160e01b039092168252519081900360200190f35b6104f0611f75565b6104f0611f84565b61041c60048036036060811015610bfa57600080fd5b506001600160a01b03813581169160208101359091169060400135611f93565b6104f0612112565b6104f060048036036040811015610c3857600080fd5b506001600160a01b038135169060200135612121565b6104f0612156565b610b2460048036036020811015610c6c57600080fd5b50356001600160a01b0316612165565b61041c60048036036040811015610c9257600080fd5b506001600160a01b03813516906020013561218f565b61049a60048036036040811015610cbe57600080fd5b5080356001600160a01b0316906020013560ff1661238d565b61041c6123cf565b61049a60048036036040811015610cf557600080fd5b506001600160a01b03813581169160200135166123d5565b61041c60048036036020811015610d2357600080fd5b50356001600160a01b03166123f5565b6104f06124c0565b61041c6124cf565b61041c60048036036040811015610d5957600080fd5b506001600160a01b0381351690602001356124d5565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b610deb604051806060016040528060328152602001612f3860329139612582565b6015546001600160a01b03838116911614610e21576001600160a01b0382166000908152600960205260409020610e21906126a6565b6001600160a01b03838116600081815260326020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fc080966e9e93529edc1b244180c245bc60f3d86f1e690a17651a5e428746a8cd9281900390910190a3505050565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b6000610efc6040518060400160405280601881526020017f5f73657450726f746f636f6c50617573656428626f6f6c290000000000000000815250612582565b6018805483151562010000810262ff0000199092169190911790915560408051918252517fd7500633dd3ddd74daa7af62f8c8404c7fe4a81da179998db851696bed004b389181900360200190a15090565b610f6f604051806060016040528060298152602001612f9460299139612582565b838260005b82811015610fe05760005b82811015610fd757610fcf898984818110610f9657fe5b905060200201356001600160a01b0316888884818110610fb257fe5b90506020020135600881118015610fc857600080fd5b50876126f0565b600101610f7f565b50600101610f74565b5050505050505050565b60166020526000908152604090205481565b60006017548280821415611045576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61104d6127a8565b6017805490859055604080518281526020810187905281517f73747d68b346dce1e932bcd238282e7ac84c01569e1f8d0469c222fdc6e9d5a4929181900390910190a160005b9350505b5050919050565b600060055482808214156110e7576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b6110ef6127a8565b6110f7612f24565b50604080516020810190915284815261110e612f24565b506040805160208101909152670c7d713b49da0000815261112d612f24565b50604080516020810190915266b1a2bc2ec50000815261114d82846127fa565b8061115d575061115d8184612801565b156111775761116d600580612808565b9550505050611097565b600580549088905560408051828152602081018a905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a1600098975050505050505050565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b601b546001600160a01b0390811690849081168214156112665760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b61126e6127a8565b6112778561286e565b601b546001600160a01b031615611290576112906128c1565b601b80546001600160a01b0319166001600160a01b038716908117909155601c859055601d849055604080518681526020810186905281517f7059037d74ee16b0fb06a4a30f3348dd2635f301f92e373c92899a25a522ef6e929181900390910190a25050505050565b6113026127a8565b61130b8161286e565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b50516033549091506001600160a01b038083169116146113d7576040805162461bcd60e51b815260206004820152601a60248201527f696e76616c6964207876732076746f6b656e2061646472657373000000000000604482015290519081900360640190fd5b6034546040516001600160a01b038085169216907f2565e1579c0926afb7113edbfd85373e85cadaa3e0346f04de19686a2bb86ed190600090a350603480546001600160a01b0319166001600160a01b0392909216919091179055565b6000600654828082141561147d576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61149e604051806060016040528060218152602001612fbd60219139612582565b670de0b6b3a76400008410156114ee576040805162461bcd60e51b815260206004820152601060248201526f0d2dcc6cadce8d2ecca40784062ca62760831b604482015290519081900360640190fd5b6006805490859055604080518281526020810187905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611093565b611559604051806060016040528060298152602001612fde60299139612582565b8281811580159061156957508082145b6115aa576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b82811015611682578484828181106115c157fe5b90506020020135602760008989858181106115d857fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000208190555086868281811061161857fe5b905060200201356001600160a01b03166001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f886868481811061165e57fe5b905060200201356040518082815260200191505060405180910390a26001016115ad565b50505050505050565b6116ac60405180606001604052806023815260200161300760239139612582565b6015546001600160a01b038381169116146116e2576001600160a01b03821660009081526009602052604090206116e2906126a6565b6001600160a01b0382166000818152602d6020908152604091829020805460ff1916851515908117909155825190815291517f03561d5280ebb02280893b1d60978e4a27e7654a149c5d0e7c2cf65389ce16949281900390910190a25050565b600d818154811061174f57fe5b6000918252602090912001546001600160a01b0316905081565b6004546000906001600160a01b0390811690839081168214156117bd5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6117c56127a8565b6117ce8461286e565b600480546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611093565b602b6020526000908152604090205481565b600a546000906001600160a01b03908116908390811682141561189a5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6118a26127a8565b6118ab8461286e565b600a80546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e929181900390910190a16000611093565b61193260405180606001604052806029815260200161302a60299139612582565b8281811580159061194257508082145b611983576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b828110156116825784848281811061199a57fe5b90506020020135601f60008989858181106119b157fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106119f157fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611a3757fe5b905060200201356040518082815260200191505060405180910390a2600101611986565b601a548180821415611aa2576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b611aaa6127a8565b601b546001600160a01b031615611ac357611ac36128c1565b601a805490849055604080518281526020810186905281517fe81d4ac15e5afa1e708e66664eddc697177423d950d133bda8262d8885e6da3b929181900390910190a150505050565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b611b936127a8565b611b9c8161286e565b6033546040516001600160a01b038084169216907ffe7fd0d872def0f65050e9f38fc6691d0c192c694a56f09b04bec5fb2ea61f2b90600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6015546001600160a01b031681565b6000611c116127a8565b611c1a8261286e565b603180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fcb20dab7409e4fb972d9adccb39530520b226ce6940d85c9523a499b950b6ea3929181900390910190a160009392505050565b60075481565b6025546001600160a01b031681565b6026546000906001600160a01b039081169083908116821415611ceb5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611cf36127a8565b611cfc8461286e565b602680546001600160a01b038681166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0f7eb572d1b3053a0a3a33c04151364cf88d163182a5e4e1088cb8e52321e08a9281900390910190a16000611093565b6015546000906001600160a01b039081169083908116821415611db55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611dbd6127a8565b611dc68461286e565b601580546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fe1ddcb2dab8e5b03cfc8c67a0d5861d91d16f7bd2612fd381faf4541d212c9b2929181900390910190a16000611093565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b6025546001600160a01b039081169082908116821415611ec55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611ecd6127a8565b611ed68361286e565b602580546001600160a01b038581166001600160a01b0319831681179093556040805191909216808252602082019390935281517fa5ea5616d5f6dbbaa62fdfcf3856723216eed485c394d9e51ec8e6d40e1d1ac1929181900390910190a150505050565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b602054600090611fab906001600160a01b0316612a88565b670de0b6b3a76400008210611ff9576040805162461bcd60e51b815260206004820152600f60248201526e70657263656e74203e3d203130302560881b604482015290519081900360640190fd5b6120028461286e565b61200b8361286e565b6020805460218054602280546001600160a01b038a81166001600160a01b0319808816821789558b8316908616179095559188905560408051958316808752968601949094528351929091169390927f29f06ea15931797ebaed313d81d100963dc22cb213cb4ce2737b5a62b1a8b1e892918290030190a1604080516001600160a01b0380851682528816602082015281517f8de763046d7b8f08b6c3d03543de1d615309417842bb5d2d62f110f65809ddac929181900390910190a1604080518281526020810187905281517f0893f8f4101baaabbeb513f96761e7a36eb837403c82cc651c292a4abdc94ed7929181900390910190a1600093505050505b9392505050565b6026546001600160a01b031681565b6008602052816000526040600020818154811061213a57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526009602052604081206001015482808214156121ef576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61221060405180606001604052806025815260200161309560259139612582565b6122198561286e565b6001600160a01b038516600090815260096020526040902061223a816126a6565b612242612f24565b506040805160208101909152858152612259612f24565b506040805160208101909152670c7d713b49da0000815261227a81836127fa565b156122955761228b60066008612808565b9550505050612385565b861580159061231e5750600480546040805163fc57d4df60e01b81526001600160a01b038c8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d602081101561231a57600080fd5b5051155b1561232f5761228b600d6009612808565b6001830180549088905560408051828152602081018a905281516001600160a01b038c16927f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5928290030190a260009650505050505b505092915050565b6001600160a01b0382166000908152602960205260408120818360088111156123b257fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b603260209081526000928352604080842090915290825290205460ff1681565b6028546000906001600160a01b0390811690839081168214156124495760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6124516127a8565b61245a8461286e565b602880546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0f1eca7612e020f6e4582bcead0573eba4b5f7b56668754c6aed82ef12057dd4929181900390910190a16000611093565b6000546001600160a01b031681565b601a5481565b60006124df612aea565b60185460ff161580156124fa5750601854610100900460ff16155b61253b576040805162461bcd60e51b815260206004820152600d60248201526c159052481a5cc81c185d5cd959609a1b604482015290519081900360640190fd5b6015546001600160a01b0316331461256057612559600e6016612808565b90506123c9565b6001600160a01b03831660009081526016602052604081208390559392505050565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156125eb5781810151838201526020016125d3565b50505050905090810190601f1680156126185780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561263657600080fd5b505afa15801561264a573d6000803e3d6000fd5b505050506040513d602081101561266057600080fd5b50516126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b805460ff166126a3576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612711906126a6565b6001600160a01b0383166000908152602960205260408120829184600881111561273757fe5b81526020810191909152604001600020805460ff191691151591909117905581600881111561276257fe5b60408051831515815290516001600160a01b038616917f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d919081900360200190a3505050565b6000546001600160a01b031633146127f8576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b565b5190511090565b5190511190565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601381111561283757fe5b83601781111561284357fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561210b57fe5b6001600160a01b0381166126a3576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b601c5415806128d85750601c546128d6612b3d565b105b156128e2576127f8565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561293257600080fd5b505afa158015612946573d6000803e3d6000fd5b505050506040513d602081101561295c57600080fd5b505190508061296c5750506127f8565b60008061298261297a612b3d565b601c54612b41565b90506000612992601a5483612b7b565b90508084106129a3578092506129a7565b8392505b601d548310156129bb5750505050506127f8565b6129c3612b3d565b601c55601b546129e6906001600160a01b0387811691168563ffffffff612bbd16565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a6957600080fd5b505af1158015612a7d573d6000803e3d6000fd5b505050505050505050565b6000546001600160a01b0316331480612aa95750336001600160a01b038216145b6126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b60185462010000900460ff16156127f8576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b4390565b600061210b8383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250612c14565b600061210b83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250612cab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612c0f908490612d2a565b505050565b60008184841115612ca35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c68578181015183820152602001612c50565b50505050905090810190601f168015612c955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000831580612cb8575082155b15612cc55750600061210b565b83830283858281612cd257fe5b04148390612d215760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c68578181015183820152602001612c50565b50949350505050565b612d3c826001600160a01b0316612ee8565b612d8d576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612dcb5780518252601f199092019160209182019101612dac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612e2d576040519150601f19603f3d011682016040523d82523d6000602084013e612e32565b606091505b509150915081612e89576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115612ee257808060200190516020811015612ea557600080fd5b5051612ee25760405162461bcd60e51b815260040180806020018281038252602a815260200180612f6a602a913960400191505060405180910390fd5b50505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612f1c57508115155b949350505050565b604051806020016040528060008152509056fe5f736574466f726365644c69717569646174696f6e466f725573657228616464726573732c616464726573732c626f6f6c295361666542455032303a204245503230206f7065726174696f6e20646964206e6f7420737563636565645f736574416374696f6e7350617573656428616464726573735b5d2c75696e74385b5d2c626f6f6c295f7365744c69717569646174696f6e496e63656e746976652875696e74323536295f7365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d295f736574466f726365644c69717569646174696f6e28616464726573732c626f6f6c295f7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d296f6c642076616c75652069732073616d65206173206e65772076616c756500006f6c6420616464726573732069732073616d65206173206e657720616464726573735f736574436f6c6c61746572616c466163746f7228616464726573732c75696e7432353629a265627a7a7231582030a79673e4aafa1d3f9a8610481e64d889e0b57fc08bc0757ace53ae4b9ffeae64736f6c63430005100032", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103f15760003560e01c80637dc0d1d011610215578063bf32442d11610125578063e37d4b79116100b8578063f445d70311610087578063f445d70314610cdf578063f519fc3014610d0d578063f851a44014610d33578063fa6331d814610d3b578063fd51a3ad14610d43576103f1565b8063e37d4b7914610c56578063e4028eee14610c7c578063e85a296014610ca8578063e875544614610cd7576103f1565b8063d24febad116100f4578063d24febad14610be4578063d3270f9914610c1a578063dce1544914610c22578063dcfbc0c714610c4e576103f1565b8063bf32442d14610ba8578063c5b4db5514610bb0578063c5f956af14610bd4578063c7ee005e14610bdc576103f1565b80639bb27d62116101a8578063b8324c7c11610177578063b8324c7c14610afe578063bb82aa5e14610b4c578063bb85745014610b54578063bbb8864a14610b7a578063bec04f7214610ba0576103f1565b80639bb27d6214610aa25780639bf34cbb14610aaa5780639cfdd9e614610ad0578063b2eafc3914610af6576103f1565b8063919a3736116101e4578063919a373614610a465780639254f5e514610a6c5780639460c8b514610a7457806394b2294b14610a9a576103f1565b80637dc0d1d0146109aa5780638a7dc165146109b25780638c1ac18a146109d85780638e8f294b146109fe576103f1565b8063425fad581161031057806352d84d1e116102a3578063607ef6c111610272578063607ef6c1146108b75780636662c7c914610975578063719f701b14610992578063765513831461099a5780637d172bd5146109a2576103f1565b806352d84d1e1461082857806355ee1fe1146108455780635dd3fc9d1461086b5780635f5af1aa14610891576103f1565b80634ef233fc116102df5780634ef233fc146106f95780634fd42e171461071f57806351a485e41461073c578063522c656b146107fa576103f1565b8063425fad58146106915780634a584432146106995780634ada90af146106bf5780634e0853db146106c7576103f1565b806326782247116103885780632ec04124116103575780632ec0412414610621578063317b0b771461063e5780634088c73e1461065b57806341a18d2c14610663576103f1565b806326782247146105145780632a6a60651461051c5780632b5d790c1461053b5780632bc7e29e146105fb576103f1565b806310b98338116103c457806310b983381461046c57806317db2163146104ae57806321af4569146104e857806324a3d6221461050c576103f1565b806302c3bcbb146103f657806304ef9d581461042e57806308e0225c146104365780630db4b4e514610464575b600080fd5b61041c6004803603602081101561040c57600080fd5b50356001600160a01b0316610d6f565b60408051918252519081900360200190f35b61041c610d81565b61041c6004803603604081101561044c57600080fd5b506001600160a01b0381358116916020013516610d87565b61041c610da4565b61049a6004803603604081101561048257600080fd5b506001600160a01b0381358116916020013516610daa565b604080519115158252519081900360200190f35b6104e6600480360360608110156104c457600080fd5b506001600160a01b038135811691602081013590911690604001351515610dca565b005b6104f0610e8f565b604080516001600160a01b039092168252519081900360200190f35b6104f0610e9e565b6104f0610ead565b61049a6004803603602081101561053257600080fd5b50351515610ebc565b6104e66004803603606081101561055157600080fd5b810190602081018135600160201b81111561056b57600080fd5b82018360208201111561057d57600080fd5b803590602001918460208302840111600160201b8311171561059e57600080fd5b919390929091602081019035600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460208302840111600160201b831117156105ee57600080fd5b9193509150351515610f4e565b61041c6004803603602081101561061157600080fd5b50356001600160a01b0316610fea565b61041c6004803603602081101561063757600080fd5b5035610ffc565b61041c6004803603602081101561065457600080fd5b503561109e565b61049a6111c8565b61041c6004803603604081101561067957600080fd5b506001600160a01b03813581169160200135166111d1565b61049a6111ee565b61041c600480360360208110156106af57600080fd5b50356001600160a01b03166111fd565b61041c61120f565b6104e6600480360360608110156106dd57600080fd5b506001600160a01b038135169060208101359060400135611215565b6104e66004803603602081101561070f57600080fd5b50356001600160a01b03166112fa565b61041c6004803603602081101561073557600080fd5b5035611434565b6104e66004803603604081101561075257600080fd5b810190602081018135600160201b81111561076c57600080fd5b82018360208201111561077e57600080fd5b803590602001918460208302840111600160201b8311171561079f57600080fd5b919390929091602081019035600160201b8111156107bc57600080fd5b8201836020820111156107ce57600080fd5b803590602001918460208302840111600160201b831117156107ef57600080fd5b509092509050611538565b6104e66004803603604081101561081057600080fd5b506001600160a01b038135169060200135151561168b565b6104f06004803603602081101561083e57600080fd5b5035611742565b61041c6004803603602081101561085b57600080fd5b50356001600160a01b0316611769565b61041c6004803603602081101561088157600080fd5b50356001600160a01b0316611834565b61041c600480360360208110156108a757600080fd5b50356001600160a01b0316611846565b6104e6600480360360408110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460208302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460208302840111600160201b8311171561096a57600080fd5b509092509050611911565b6104e66004803603602081101561098b57600080fd5b5035611a5b565b61041c611b0c565b61049a611b12565b6104f0611b20565b6104f0611b2f565b61041c600480360360208110156109c857600080fd5b50356001600160a01b0316611b3e565b61049a600480360360208110156109ee57600080fd5b50356001600160a01b0316611b50565b610a2460048036036020811015610a1457600080fd5b50356001600160a01b0316611b65565b6040805193151584526020840192909252151582820152519081900360600190f35b6104e660048036036020811015610a5c57600080fd5b50356001600160a01b0316611b8b565b6104f0611bf8565b61041c60048036036020811015610a8a57600080fd5b50356001600160a01b0316611c07565b61041c611c82565b6104f0611c88565b61041c60048036036020811015610ac057600080fd5b50356001600160a01b0316611c97565b61041c60048036036020811015610ae657600080fd5b50356001600160a01b0316611d61565b6104f0611e2c565b610b2460048036036020811015610b1457600080fd5b50356001600160a01b0316611e3b565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104f0611e65565b6104e660048036036020811015610b6a57600080fd5b50356001600160a01b0316611e74565b61041c60048036036020811015610b9057600080fd5b50356001600160a01b0316611f3b565b61041c611f4d565b6104f0611f53565b610bb8611f62565b604080516001600160e01b039092168252519081900360200190f35b6104f0611f75565b6104f0611f84565b61041c60048036036060811015610bfa57600080fd5b506001600160a01b03813581169160208101359091169060400135611f93565b6104f0612112565b6104f060048036036040811015610c3857600080fd5b506001600160a01b038135169060200135612121565b6104f0612156565b610b2460048036036020811015610c6c57600080fd5b50356001600160a01b0316612165565b61041c60048036036040811015610c9257600080fd5b506001600160a01b03813516906020013561218f565b61049a60048036036040811015610cbe57600080fd5b5080356001600160a01b0316906020013560ff1661238d565b61041c6123cf565b61049a60048036036040811015610cf557600080fd5b506001600160a01b03813581169160200135166123d5565b61041c60048036036020811015610d2357600080fd5b50356001600160a01b03166123f5565b6104f06124c0565b61041c6124cf565b61041c60048036036040811015610d5957600080fd5b506001600160a01b0381351690602001356124d5565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b610deb604051806060016040528060328152602001612f3860329139612582565b6015546001600160a01b03838116911614610e21576001600160a01b0382166000908152600960205260409020610e21906126a6565b6001600160a01b03838116600081815260326020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fc080966e9e93529edc1b244180c245bc60f3d86f1e690a17651a5e428746a8cd9281900390910190a3505050565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b6000610efc6040518060400160405280601881526020017f5f73657450726f746f636f6c50617573656428626f6f6c290000000000000000815250612582565b6018805483151562010000810262ff0000199092169190911790915560408051918252517fd7500633dd3ddd74daa7af62f8c8404c7fe4a81da179998db851696bed004b389181900360200190a15090565b610f6f604051806060016040528060298152602001612f9460299139612582565b838260005b82811015610fe05760005b82811015610fd757610fcf898984818110610f9657fe5b905060200201356001600160a01b0316888884818110610fb257fe5b90506020020135600881118015610fc857600080fd5b50876126f0565b600101610f7f565b50600101610f74565b5050505050505050565b60166020526000908152604090205481565b60006017548280821415611045576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61104d6127a8565b6017805490859055604080518281526020810187905281517f73747d68b346dce1e932bcd238282e7ac84c01569e1f8d0469c222fdc6e9d5a4929181900390910190a160005b9350505b5050919050565b600060055482808214156110e7576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b6110ef6127a8565b6110f7612f24565b50604080516020810190915284815261110e612f24565b506040805160208101909152670c7d713b49da0000815261112d612f24565b50604080516020810190915266b1a2bc2ec50000815261114d82846127fa565b8061115d575061115d8184612801565b156111775761116d600580612808565b9550505050611097565b600580549088905560408051828152602081018a905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a1600098975050505050505050565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b601b546001600160a01b0390811690849081168214156112665760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b61126e6127a8565b6112778561286e565b601b546001600160a01b031615611290576112906128c1565b601b80546001600160a01b0319166001600160a01b038716908117909155601c859055601d849055604080518681526020810186905281517f7059037d74ee16b0fb06a4a30f3348dd2635f301f92e373c92899a25a522ef6e929181900390910190a25050505050565b6113026127a8565b61130b8161286e565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b50516033549091506001600160a01b038083169116146113d7576040805162461bcd60e51b815260206004820152601a60248201527f696e76616c6964207876732076746f6b656e2061646472657373000000000000604482015290519081900360640190fd5b6034546040516001600160a01b038085169216907f2565e1579c0926afb7113edbfd85373e85cadaa3e0346f04de19686a2bb86ed190600090a350603480546001600160a01b0319166001600160a01b0392909216919091179055565b6000600654828082141561147d576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61149e604051806060016040528060218152602001612fbd60219139612582565b670de0b6b3a76400008410156114ee576040805162461bcd60e51b815260206004820152601060248201526f0d2dcc6cadce8d2ecca40784062ca62760831b604482015290519081900360640190fd5b6006805490859055604080518281526020810187905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611093565b611559604051806060016040528060298152602001612fde60299139612582565b8281811580159061156957508082145b6115aa576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b82811015611682578484828181106115c157fe5b90506020020135602760008989858181106115d857fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000208190555086868281811061161857fe5b905060200201356001600160a01b03166001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f886868481811061165e57fe5b905060200201356040518082815260200191505060405180910390a26001016115ad565b50505050505050565b6116ac60405180606001604052806023815260200161300760239139612582565b6015546001600160a01b038381169116146116e2576001600160a01b03821660009081526009602052604090206116e2906126a6565b6001600160a01b0382166000818152602d6020908152604091829020805460ff1916851515908117909155825190815291517f03561d5280ebb02280893b1d60978e4a27e7654a149c5d0e7c2cf65389ce16949281900390910190a25050565b600d818154811061174f57fe5b6000918252602090912001546001600160a01b0316905081565b6004546000906001600160a01b0390811690839081168214156117bd5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6117c56127a8565b6117ce8461286e565b600480546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611093565b602b6020526000908152604090205481565b600a546000906001600160a01b03908116908390811682141561189a5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6118a26127a8565b6118ab8461286e565b600a80546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e929181900390910190a16000611093565b61193260405180606001604052806029815260200161302a60299139612582565b8281811580159061194257508082145b611983576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b828110156116825784848281811061199a57fe5b90506020020135601f60008989858181106119b157fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106119f157fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611a3757fe5b905060200201356040518082815260200191505060405180910390a2600101611986565b601a548180821415611aa2576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b611aaa6127a8565b601b546001600160a01b031615611ac357611ac36128c1565b601a805490849055604080518281526020810186905281517fe81d4ac15e5afa1e708e66664eddc697177423d950d133bda8262d8885e6da3b929181900390910190a150505050565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b611b936127a8565b611b9c8161286e565b6033546040516001600160a01b038084169216907ffe7fd0d872def0f65050e9f38fc6691d0c192c694a56f09b04bec5fb2ea61f2b90600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6015546001600160a01b031681565b6000611c116127a8565b611c1a8261286e565b603180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fcb20dab7409e4fb972d9adccb39530520b226ce6940d85c9523a499b950b6ea3929181900390910190a160009392505050565b60075481565b6025546001600160a01b031681565b6026546000906001600160a01b039081169083908116821415611ceb5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611cf36127a8565b611cfc8461286e565b602680546001600160a01b038681166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0f7eb572d1b3053a0a3a33c04151364cf88d163182a5e4e1088cb8e52321e08a9281900390910190a16000611093565b6015546000906001600160a01b039081169083908116821415611db55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611dbd6127a8565b611dc68461286e565b601580546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fe1ddcb2dab8e5b03cfc8c67a0d5861d91d16f7bd2612fd381faf4541d212c9b2929181900390910190a16000611093565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b6025546001600160a01b039081169082908116821415611ec55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611ecd6127a8565b611ed68361286e565b602580546001600160a01b038581166001600160a01b0319831681179093556040805191909216808252602082019390935281517fa5ea5616d5f6dbbaa62fdfcf3856723216eed485c394d9e51ec8e6d40e1d1ac1929181900390910190a150505050565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b602054600090611fab906001600160a01b0316612a88565b670de0b6b3a76400008210611ff9576040805162461bcd60e51b815260206004820152600f60248201526e70657263656e74203e3d203130302560881b604482015290519081900360640190fd5b6120028461286e565b61200b8361286e565b6020805460218054602280546001600160a01b038a81166001600160a01b0319808816821789558b8316908616179095559188905560408051958316808752968601949094528351929091169390927f29f06ea15931797ebaed313d81d100963dc22cb213cb4ce2737b5a62b1a8b1e892918290030190a1604080516001600160a01b0380851682528816602082015281517f8de763046d7b8f08b6c3d03543de1d615309417842bb5d2d62f110f65809ddac929181900390910190a1604080518281526020810187905281517f0893f8f4101baaabbeb513f96761e7a36eb837403c82cc651c292a4abdc94ed7929181900390910190a1600093505050505b9392505050565b6026546001600160a01b031681565b6008602052816000526040600020818154811061213a57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526009602052604081206001015482808214156121ef576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61221060405180606001604052806025815260200161309560259139612582565b6122198561286e565b6001600160a01b038516600090815260096020526040902061223a816126a6565b612242612f24565b506040805160208101909152858152612259612f24565b506040805160208101909152670c7d713b49da0000815261227a81836127fa565b156122955761228b60066008612808565b9550505050612385565b861580159061231e5750600480546040805163fc57d4df60e01b81526001600160a01b038c8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d602081101561231a57600080fd5b5051155b1561232f5761228b600d6009612808565b6001830180549088905560408051828152602081018a905281516001600160a01b038c16927f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5928290030190a260009650505050505b505092915050565b6001600160a01b0382166000908152602960205260408120818360088111156123b257fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b603260209081526000928352604080842090915290825290205460ff1681565b6028546000906001600160a01b0390811690839081168214156124495760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6124516127a8565b61245a8461286e565b602880546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0f1eca7612e020f6e4582bcead0573eba4b5f7b56668754c6aed82ef12057dd4929181900390910190a16000611093565b6000546001600160a01b031681565b601a5481565b60006124df612aea565b60185460ff161580156124fa5750601854610100900460ff16155b61253b576040805162461bcd60e51b815260206004820152600d60248201526c159052481a5cc81c185d5cd959609a1b604482015290519081900360640190fd5b6015546001600160a01b0316331461256057612559600e6016612808565b90506123c9565b6001600160a01b03831660009081526016602052604081208390559392505050565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156125eb5781810151838201526020016125d3565b50505050905090810190601f1680156126185780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561263657600080fd5b505afa15801561264a573d6000803e3d6000fd5b505050506040513d602081101561266057600080fd5b50516126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b805460ff166126a3576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612711906126a6565b6001600160a01b0383166000908152602960205260408120829184600881111561273757fe5b81526020810191909152604001600020805460ff191691151591909117905581600881111561276257fe5b60408051831515815290516001600160a01b038616917f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d919081900360200190a3505050565b6000546001600160a01b031633146127f8576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b565b5190511090565b5190511190565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601381111561283757fe5b83601781111561284357fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561210b57fe5b6001600160a01b0381166126a3576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b601c5415806128d85750601c546128d6612b3d565b105b156128e2576127f8565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561293257600080fd5b505afa158015612946573d6000803e3d6000fd5b505050506040513d602081101561295c57600080fd5b505190508061296c5750506127f8565b60008061298261297a612b3d565b601c54612b41565b90506000612992601a5483612b7b565b90508084106129a3578092506129a7565b8392505b601d548310156129bb5750505050506127f8565b6129c3612b3d565b601c55601b546129e6906001600160a01b0387811691168563ffffffff612bbd16565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a6957600080fd5b505af1158015612a7d573d6000803e3d6000fd5b505050505050505050565b6000546001600160a01b0316331480612aa95750336001600160a01b038216145b6126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b60185462010000900460ff16156127f8576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b4390565b600061210b8383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250612c14565b600061210b83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250612cab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612c0f908490612d2a565b505050565b60008184841115612ca35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c68578181015183820152602001612c50565b50505050905090810190601f168015612c955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000831580612cb8575082155b15612cc55750600061210b565b83830283858281612cd257fe5b04148390612d215760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c68578181015183820152602001612c50565b50949350505050565b612d3c826001600160a01b0316612ee8565b612d8d576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612dcb5780518252601f199092019160209182019101612dac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612e2d576040519150601f19603f3d011682016040523d82523d6000602084013e612e32565b606091505b509150915081612e89576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115612ee257808060200190516020811015612ea557600080fd5b5051612ee25760405162461bcd60e51b815260040180806020018281038252602a815260200180612f6a602a913960400191505060405180910390fd5b50505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612f1c57508115155b949350505050565b604051806020016040528060008152509056fe5f736574466f726365644c69717569646174696f6e466f725573657228616464726573732c616464726573732c626f6f6c295361666542455032303a204245503230206f7065726174696f6e20646964206e6f7420737563636565645f736574416374696f6e7350617573656428616464726573735b5d2c75696e74385b5d2c626f6f6c295f7365744c69717569646174696f6e496e63656e746976652875696e74323536295f7365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d295f736574466f726365644c69717569646174696f6e28616464726573732c626f6f6c295f7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d296f6c642076616c75652069732073616d65206173206e65772076616c756500006f6c6420616464726573732069732073616d65206173206e657720616464726573735f736574436f6c6c61746572616c466163746f7228616464726573732c75696e7432353629a265627a7a7231582030a79673e4aafa1d3f9a8610481e64d889e0b57fc08bc0757ace53ae4b9ffeae64736f6c63430005100032", + "numDeployments": 3, + "solcInputHash": "7674fc0eb5134fe9ab2419cd8945df4b", + "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"pauseState\",\"type\":\"bool\"}],\"name\":\"ActionPausedMarket\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"ActionProtocolPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DistributedVAIVaultVenus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"error\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"info\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"detail\",\"type\":\"uint256\"}],\"name\":\"Failure\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"IsForcedLiquidationEnabledForUserUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"IsForcedLiquidationEnabledUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"MarketEntered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlAddress\",\"type\":\"address\"}],\"name\":\"NewAccessControl\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBorrowCap\",\"type\":\"uint256\"}],\"name\":\"NewBorrowCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCloseFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCloseFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCollateralFactorMantissa\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"NewCollateralFactor\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldComptrollerLens\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newComptrollerLens\",\"type\":\"address\"}],\"name\":\"NewComptrollerLens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":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\":\"address\",\"name\":\"oldLiquidatorContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLiquidatorContract\",\"type\":\"address\"}],\"name\":\"NewLiquidatorContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldPauseGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPauseGuardian\",\"type\":\"address\"}],\"name\":\"NewPauseGuardian\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract PriceOracle\",\"name\":\"oldPriceOracle\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract PriceOracle\",\"name\":\"newPriceOracle\",\"type\":\"address\"}],\"name\":\"NewPriceOracle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IPrime\",\"name\":\"oldPrimeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract IPrime\",\"name\":\"newPrimeToken\",\"type\":\"address\"}],\"name\":\"NewPrimeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSupplyCap\",\"type\":\"uint256\"}],\"name\":\"NewSupplyCap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldTreasuryAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTreasuryAddress\",\"type\":\"address\"}],\"name\":\"NewTreasuryAddress\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldTreasuryGuardian\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTreasuryGuardian\",\"type\":\"address\"}],\"name\":\"NewTreasuryGuardian\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldTreasuryPercent\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newTreasuryPercent\",\"type\":\"uint256\"}],\"name\":\"NewTreasuryPercent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract VAIControllerInterface\",\"name\":\"oldVAIController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract VAIControllerInterface\",\"name\":\"newVAIController\",\"type\":\"address\"}],\"name\":\"NewVAIController\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVAIMintRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVAIMintRate\",\"type\":\"uint256\"}],\"name\":\"NewVAIMintRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"releaseStartBlock_\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"releaseInterval_\",\"type\":\"uint256\"}],\"name\":\"NewVAIVaultInfo\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldVenusVAIVaultRate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newVenusVAIVaultRate\",\"type\":\"uint256\"}],\"name\":\"NewVenusVAIVaultRate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldXVS\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newXVS\",\"type\":\"address\"}],\"name\":\"NewXVSToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldXVSVToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newXVSVToken\",\"type\":\"address\"}],\"name\":\"NewXVSVToken\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAccessControlAddress\",\"type\":\"address\"}],\"name\":\"_setAccessControl\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"markets_\",\"type\":\"address[]\"},{\"internalType\":\"enum ComptrollerTypes.Action[]\",\"name\":\"actions_\",\"type\":\"uint8[]\"},{\"internalType\":\"bool\",\"name\":\"paused_\",\"type\":\"bool\"}],\"name\":\"_setActionsPaused\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newCloseFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"_setCloseFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken\",\"name\":\"vToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newCollateralFactorMantissa\",\"type\":\"uint256\"}],\"name\":\"_setCollateralFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"comptrollerLens_\",\"type\":\"address\"}],\"name\":\"_setComptrollerLens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"_setForcedLiquidation\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"borrower\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"vTokenBorrowed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enable\",\"type\":\"bool\"}],\"name\":\"_setForcedLiquidationForUser\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newLiquidationIncentiveMantissa\",\"type\":\"uint256\"}],\"name\":\"_setLiquidationIncentive\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newLiquidatorContract_\",\"type\":\"address\"}],\"name\":\"_setLiquidatorContract\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newBorrowCaps\",\"type\":\"uint256[]\"}],\"name\":\"_setMarketBorrowCaps\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VToken[]\",\"name\":\"vTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"newSupplyCaps\",\"type\":\"uint256[]\"}],\"name\":\"_setMarketSupplyCaps\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPauseGuardian\",\"type\":\"address\"}],\"name\":\"_setPauseGuardian\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"newOracle\",\"type\":\"address\"}],\"name\":\"_setPriceOracle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"_prime\",\"type\":\"address\"}],\"name\":\"_setPrimeToken\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"_setProtocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newTreasuryGuardian\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newTreasuryAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newTreasuryPercent\",\"type\":\"uint256\"}],\"name\":\"_setTreasuryData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"vaiController_\",\"type\":\"address\"}],\"name\":\"_setVAIController\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newVAIMintRate\",\"type\":\"uint256\"}],\"name\":\"_setVAIMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"vault_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"releaseStartBlock_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minReleaseAmount_\",\"type\":\"uint256\"}],\"name\":\"_setVAIVaultInfo\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"venusVAIVaultRate_\",\"type\":\"uint256\"}],\"name\":\"_setVenusVAIVaultRate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"xvs_\",\"type\":\"address\"}],\"name\":\"_setXVSToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"xvsVToken_\",\"type\":\"address\"}],\"name\":\"_setXVSVToken\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"accountAssets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"enum ComptrollerTypes.Action\",\"name\":\"action\",\"type\":\"uint8\"}],\"name\":\"actionPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allMarkets\",\"outputs\":[{\"internalType\":\"contract VToken\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedDelegates\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"borrowCapGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"borrowCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"closeFactorMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"comptrollerLens\",\"outputs\":[{\"internalType\":\"contract ComptrollerLensInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getXVSAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isForcedLiquidationEnabledForUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidationIncentiveMantissa\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"liquidatorContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"markets\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isListed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralFactorMantissa\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isVenus\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"minReleaseAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"mintVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"mintedVAIs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract PriceOracle\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pauseGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pendingComptrollerImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"prime\",\"outputs\":[{\"internalType\":\"contract IPrime\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"protocolPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"releaseStartBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"repayVAIGuardianPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"setMintedVAIOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"supplyCaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryGuardian\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"treasuryPercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiController\",\"outputs\":[{\"internalType\":\"contract VAIControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiMintRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaiVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusAccrued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowSpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusBorrowerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusInitialIndex\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplySpeeds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"venusSupplyState\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"index\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"block\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"venusVAIVaultRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"This facet contains all the setters for the states\",\"methods\":{\"_setAccessControl(address)\":{\"details\":\"Allows the contract admin to set the address of access control of this contract\",\"params\":{\"newAccessControlAddress\":\"New address for the access control\"},\"return\":\"uint256 0=success, otherwise will revert\"},\"_setActionsPaused(address[],uint8[],bool)\":{\"details\":\"Allows a privileged role to pause/unpause the protocol action state\",\"params\":{\"actions_\":\"List of action ids to pause/unpause\",\"markets_\":\"Markets to pause/unpause the actions on\",\"paused_\":\"The new paused state (true=paused, false=unpaused)\"}},\"_setCloseFactor(uint256)\":{\"details\":\"Allows the contract admin to set the closeFactor used to liquidate borrows\",\"params\":{\"newCloseFactorMantissa\":\"New close factor, scaled by 1e18\"},\"return\":\"uint256 0=success, otherwise will revert\"},\"_setCollateralFactor(address,uint256)\":{\"details\":\"Allows a privileged role to set the collateralFactorMantissa\",\"params\":{\"newCollateralFactorMantissa\":\"The new collateral factor, scaled by 1e18\",\"vToken\":\"The market to set the factor on\"},\"return\":\"uint256 0=success, otherwise a failure. (See ErrorReporter for details)\"},\"_setComptrollerLens(address)\":{\"details\":\"Set ComptrollerLens contract address\",\"params\":{\"comptrollerLens_\":\"The new ComptrollerLens contract address to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setForcedLiquidation(address,bool)\":{\"details\":\"Allows a privileged role to set enable/disable forced liquidations\",\"params\":{\"enable\":\"Whether to enable forced liquidations\",\"vTokenBorrowed\":\"Borrowed vToken\"}},\"_setForcedLiquidationForUser(address,address,bool)\":{\"params\":{\"borrower\":\"The address of the borrower\",\"enable\":\"Whether to enable forced liquidations\",\"vTokenBorrowed\":\"Borrowed vToken\"}},\"_setLiquidationIncentive(uint256)\":{\"details\":\"Allows a privileged role to set the liquidationIncentiveMantissa\",\"params\":{\"newLiquidationIncentiveMantissa\":\"New liquidationIncentive scaled by 1e18\"},\"return\":\"uint256 0=success, otherwise a failure. (See ErrorReporter for details)\"},\"_setLiquidatorContract(address)\":{\"details\":\"Allows the contract admin to update the address of liquidator contract\",\"params\":{\"newLiquidatorContract_\":\"The new address of the liquidator contract\"}},\"_setMarketBorrowCaps(address[],uint256[])\":{\"details\":\"Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed\",\"params\":{\"newBorrowCaps\":\"The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed\",\"vTokens\":\"The addresses of the markets (tokens) to change the borrow caps for\"}},\"_setMarketSupplyCaps(address[],uint256[])\":{\"details\":\"Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\",\"params\":{\"newSupplyCaps\":\"The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\",\"vTokens\":\"The addresses of the markets (tokens) to change the supply caps for\"}},\"_setPauseGuardian(address)\":{\"details\":\"Allows the contract admin to change the Pause Guardian\",\"params\":{\"newPauseGuardian\":\"The address of the new Pause Guardian\"},\"return\":\"uint256 0=success, otherwise a failure. (See enum Error for details)\"},\"_setPriceOracle(address)\":{\"details\":\"Allows the contract admin to set a new price oracle used by the Comptroller\",\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setPrimeToken(address)\":{\"return\":\"uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setProtocolPaused(bool)\":{\"details\":\"Allows a privileged role to pause/unpause protocol\",\"params\":{\"state\":\"The new state (true=paused, false=unpaused)\"},\"return\":\"bool The updated state of the protocol\"},\"_setTreasuryData(address,address,uint256)\":{\"params\":{\"newTreasuryAddress\":\"The new address of the treasury to be set\",\"newTreasuryGuardian\":\"The new address of the treasury guardian to be set\",\"newTreasuryPercent\":\"The new treasury percent to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIController(address)\":{\"details\":\"Admin function to set a new VAI controller\",\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIMintRate(uint256)\":{\"params\":{\"newVAIMintRate\":\"The new VAI mint rate to be set\"},\"return\":\"uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\"},\"_setVAIVaultInfo(address,uint256,uint256)\":{\"params\":{\"minReleaseAmount_\":\"The minimum release amount to VAI Vault\",\"releaseStartBlock_\":\"The start block of release to VAI Vault\",\"vault_\":\"The address of the VAI Vault\"}},\"_setVenusVAIVaultRate(uint256)\":{\"params\":{\"venusVAIVaultRate_\":\"The amount of XVS wei per block to distribute to VAI Vault\"}},\"_setXVSToken(address)\":{\"params\":{\"xvs_\":\"The address of the XVS token\"}},\"_setXVSVToken(address)\":{\"params\":{\"xvsVToken_\":\"The address of the XVS vToken\"}},\"actionPaused(address,uint8)\":{\"params\":{\"action\":\"Action id\",\"market\":\"vToken address\"}},\"getXVSAddress()\":{\"return\":\"The address of XVS token\"},\"setMintedVAIOf(address,uint256)\":{\"params\":{\"amount\":\"The amount of VAI to set to the account\",\"owner\":\"The address of the account to set\"},\"return\":\"The number of minted VAI by `owner`\"}},\"title\":\"SetterFacet\"},\"userdoc\":{\"methods\":{\"_setAccessControl(address)\":{\"notice\":\"Sets the address of the access control of this contract\"},\"_setActionsPaused(address[],uint8[],bool)\":{\"notice\":\"Pause/unpause certain actions\"},\"_setCloseFactor(uint256)\":{\"notice\":\"Sets the closeFactor used when liquidating borrows\"},\"_setCollateralFactor(address,uint256)\":{\"notice\":\"Sets the collateralFactor for a market\"},\"_setForcedLiquidation(address,bool)\":{\"notice\":\"Enables forced liquidations for a market. If forced liquidation is enabled, borrows in the market may be liquidated regardless of the account liquidity\"},\"_setForcedLiquidationForUser(address,address,bool)\":{\"notice\":\"Enables forced liquidations for user's borrows in a certain market. If forced liquidation is enabled, user's borrows in the market may be liquidated regardless of the account liquidity. Forced liquidation may be enabled for a user even if it is not enabled for the entire market.\"},\"_setLiquidationIncentive(uint256)\":{\"notice\":\"Sets liquidationIncentive\"},\"_setLiquidatorContract(address)\":{\"notice\":\"Update the address of the liquidator contract\"},\"_setMarketBorrowCaps(address[],uint256[])\":{\"notice\":\"Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\"},\"_setMarketSupplyCaps(address[],uint256[])\":{\"notice\":\"Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\"},\"_setPauseGuardian(address)\":{\"notice\":\"Admin function to change the Pause Guardian\"},\"_setPriceOracle(address)\":{\"notice\":\"Sets a new price oracle for the comptroller\"},\"_setPrimeToken(address)\":{\"notice\":\"Sets the prime token contract for the comptroller\"},\"_setProtocolPaused(bool)\":{\"notice\":\"Set whole protocol pause/unpause state\"},\"_setTreasuryData(address,address,uint256)\":{\"notice\":\"Set the treasury data.\"},\"_setVAIController(address)\":{\"notice\":\"Sets a new VAI controller\"},\"_setVAIMintRate(uint256)\":{\"notice\":\"Set the VAI mint rate\"},\"_setVAIVaultInfo(address,uint256,uint256)\":{\"notice\":\"Set the VAI Vault infos\"},\"_setVenusVAIVaultRate(uint256)\":{\"notice\":\"Set the amount of XVS distributed per block to VAI Vault\"},\"_setXVSToken(address)\":{\"notice\":\"Set the address of the XVS token\"},\"_setXVSVToken(address)\":{\"notice\":\"Set the address of the XVS vToken\"},\"actionPaused(address,uint8)\":{\"notice\":\"Checks if a certain action is paused on a market\"},\"getXVSAddress()\":{\"notice\":\"Returns the XVS address\"},\"setMintedVAIOf(address,uint256)\":{\"notice\":\"Set the minted VAI amount of the `owner`\"}},\"notice\":\"This facet contract contains all the configurational setter functions\"}},\"settings\":{\"compilationTarget\":{\"contracts/Comptroller/Diamond/facets/SetterFacet.sol\":\"SetterFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.5.16;\\n\\n/**\\n * @title IAccessControlManagerV5\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\\n */\\ninterface IAccessControlManagerV5 {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n\\n /**\\n * @notice Gives a function call permission to one single account\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleGranted} event.\\n * @param contractAddress address of contract for which call permissions will be granted\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n /**\\n * @notice Revokes an account's permission to a particular function call\\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\\n * \\t\\tMay emit a {RoleRevoked} event.\\n * @param contractAddress address of contract for which call permissions will be revoked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n */\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n /**\\n * @notice Verifies if the given account can call a praticular contract's function\\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\\n * @param account address (eoa or contract) for which call permissions will be checked\\n * @param functionSig signature e.g. \\\"functionName(uint,bool)\\\"\\n * @return false if the user account cannot call the particular contract function\\n *\\n */\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x3563db4c75f7aa0b8a982bab591907dda192438a2368511b62a9c587a3e54226\"},\"contracts/Comptroller/ComptrollerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport \\\"../Oracle/PriceOracle.sol\\\";\\nimport \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerTypes } from \\\"./ComptrollerStorage.sol\\\";\\n\\ncontract ComptrollerInterface {\\n /// @notice Indicator that this is a Comptroller contract (for inspection)\\n bool public constant isComptroller = true;\\n\\n /*** Assets You Are In ***/\\n\\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\\n\\n function exitMarket(address vToken) external returns (uint);\\n\\n /*** Policy Hooks ***/\\n\\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\\n\\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\\n\\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\\n\\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n function repayBorrowAllowed(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function repayBorrowVerify(\\n address vToken,\\n address payer,\\n address borrower,\\n uint repayAmount,\\n uint borrowerIndex\\n ) external;\\n\\n function liquidateBorrowAllowed(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount\\n ) external returns (uint);\\n\\n function liquidateBorrowVerify(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n uint seizeTokens\\n ) external;\\n\\n function seizeAllowed(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external returns (uint);\\n\\n function seizeVerify(\\n address vTokenCollateral,\\n address vTokenBorrowed,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) external;\\n\\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\\n\\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n /*** Liquidity/Liquidation Calculations ***/\\n\\n function liquidateCalculateSeizeTokens(\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address vTokenCollateral,\\n uint repayAmount\\n ) external view returns (uint, uint);\\n\\n function getXVSAddress() public view returns (address);\\n\\n function markets(address) external view returns (bool, uint);\\n\\n function oracle() external view returns (PriceOracle);\\n\\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\\n\\n function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n function claimVenus(address) external;\\n\\n function venusAccrued(address) external view returns (uint);\\n\\n function venusSupplySpeeds(address) external view returns (uint);\\n\\n function venusBorrowSpeeds(address) external view returns (uint);\\n\\n function getAllMarkets() external view returns (VToken[] memory);\\n\\n function venusSupplierIndex(address, address) external view returns (uint);\\n\\n function venusInitialIndex() external view returns (uint224);\\n\\n function venusBorrowerIndex(address, address) external view returns (uint);\\n\\n function venusBorrowState(address) external view returns (uint224, uint32);\\n\\n function venusSupplyState(address) external view returns (uint224, uint32);\\n\\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n function vaiController() external view returns (VAIControllerInterface);\\n\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n function protocolPaused() external view returns (bool);\\n\\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\\n\\n function mintedVAIs(address user) external view returns (uint);\\n\\n function vaiMintRate() external view returns (uint);\\n}\\n\\ninterface IVAIVault {\\n function updatePendingRewards() external;\\n}\\n\\ninterface IComptroller {\\n function liquidationIncentiveMantissa() external view returns (uint);\\n\\n /*** Treasury Data ***/\\n function treasuryAddress() external view returns (address);\\n\\n function treasuryPercent() external view returns (uint);\\n}\\n\",\"keccak256\":\"0x4f4965dd8614b455952a2ef186fd8a509affbc56078a4aa8702f46d4c8209793\"},\"contracts/Comptroller/ComptrollerLensInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ninterface ComptrollerLensInterface {\\n function liquidateCalculateSeizeTokens(\\n address comptroller,\\n address vTokenBorrowed,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function liquidateVAICalculateSeizeTokens(\\n address comptroller,\\n address vTokenCollateral,\\n uint actualRepayAmount\\n ) external view returns (uint, uint);\\n\\n function getHypotheticalAccountLiquidity(\\n address comptroller,\\n address account,\\n VToken vTokenModify,\\n uint redeemTokens,\\n uint borrowAmount\\n ) external view returns (uint, uint, uint);\\n}\\n\",\"keccak256\":\"0xc824e034221740c1957891547c78a123b595017cf102629454a04d36637e9c4a\"},\"contracts/Comptroller/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity ^0.5.16;\\n\\nimport { VToken } from \\\"../Tokens/VTokens/VToken.sol\\\";\\nimport { PriceOracle } from \\\"../Oracle/PriceOracle.sol\\\";\\nimport { VAIControllerInterface } from \\\"../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"./ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ComptrollerTypes {\\n enum Action {\\n MINT,\\n REDEEM,\\n BORROW,\\n REPAY,\\n SEIZE,\\n LIQUIDATE,\\n TRANSFER,\\n ENTER_MARKET,\\n EXIT_MARKET\\n }\\n}\\n\\ncontract UnitrollerAdminStorage {\\n /**\\n * @notice Administrator for this contract\\n */\\n address public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address public pendingAdmin;\\n\\n /**\\n * @notice Active brains of Unitroller\\n */\\n address public comptrollerImplementation;\\n\\n /**\\n * @notice Pending brains of Unitroller\\n */\\n address public pendingComptrollerImplementation;\\n}\\n\\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\\n /**\\n * @notice Oracle which gives the price of any given asset\\n */\\n PriceOracle public oracle;\\n\\n /**\\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n */\\n uint256 public closeFactorMantissa;\\n\\n /**\\n * @notice Multiplier representing the discount on collateral that a liquidator receives\\n */\\n uint256 public liquidationIncentiveMantissa;\\n\\n /**\\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\\n */\\n uint256 public maxAssets;\\n\\n /**\\n * @notice Per-account mapping of \\\"assets you are in\\\", capped by maxAssets\\n */\\n mapping(address => VToken[]) public accountAssets;\\n\\n struct Market {\\n /// @notice Whether or not this market is listed\\n bool isListed;\\n /**\\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\\n * For instance, 0.9 to allow borrowing 90% of collateral value.\\n * Must be between 0 and 1, and stored as a mantissa.\\n */\\n uint256 collateralFactorMantissa;\\n /// @notice Per-market mapping of \\\"accounts in this asset\\\"\\n mapping(address => bool) accountMembership;\\n /// @notice Whether or not this market receives XVS\\n bool isVenus;\\n }\\n\\n /**\\n * @notice Official mapping of vTokens -> Market metadata\\n * @dev Used e.g. to determine if a market is supported\\n */\\n mapping(address => Market) public markets;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n address public pauseGuardian;\\n\\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\\n bool private _mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool private _borrowGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal transferGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n bool internal seizeGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal mintGuardianPaused;\\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\\n mapping(address => bool) internal borrowGuardianPaused;\\n\\n struct VenusMarketState {\\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\\n uint224 index;\\n /// @notice The block number the index was last updated at\\n uint32 block;\\n }\\n\\n /// @notice A list of all markets\\n VToken[] public allMarkets;\\n\\n /// @notice The rate at which the flywheel distributes XVS, per block\\n uint256 internal venusRate;\\n\\n /// @notice The portion of venusRate that each market currently receives\\n mapping(address => uint256) internal venusSpeeds;\\n\\n /// @notice The Venus market supply state for each market\\n mapping(address => VenusMarketState) public venusSupplyState;\\n\\n /// @notice The Venus market borrow state for each market\\n mapping(address => VenusMarketState) public venusBorrowState;\\n\\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\\n\\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\\n\\n /// @notice The XVS accrued but not yet transferred to each user\\n mapping(address => uint256) public venusAccrued;\\n\\n /// @notice The Address of VAIController\\n VAIControllerInterface public vaiController;\\n\\n /// @notice The minted VAI amount to each user\\n mapping(address => uint256) public mintedVAIs;\\n\\n /// @notice VAI Mint Rate as a percentage\\n uint256 public vaiMintRate;\\n\\n /**\\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\\n */\\n bool public mintVAIGuardianPaused;\\n bool public repayVAIGuardianPaused;\\n\\n /**\\n * @notice Pause/Unpause whole protocol actions\\n */\\n bool public protocolPaused;\\n\\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\\n uint256 private venusVAIRate;\\n}\\n\\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\\n uint256 public venusVAIVaultRate;\\n\\n // address of VAI Vault\\n address public vaiVaultAddress;\\n\\n // start block of release to VAI Vault\\n uint256 public releaseStartBlock;\\n\\n // minimum release amount to VAI Vault\\n uint256 public minReleaseAmount;\\n}\\n\\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\\n address public borrowCapGuardian;\\n\\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address.\\n mapping(address => uint256) public borrowCaps;\\n}\\n\\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\\n /// @notice Treasury Guardian address\\n address public treasuryGuardian;\\n\\n /// @notice Treasury address\\n address public treasuryAddress;\\n\\n /// @notice Fee percent of accrued interest with decimal 18\\n uint256 public treasuryPercent;\\n}\\n\\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\\n mapping(address => uint256) private venusContributorSpeeds;\\n\\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\\n mapping(address => uint256) private lastContributorBlock;\\n}\\n\\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\\n address public liquidatorContract;\\n}\\n\\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\\n ComptrollerLensInterface public comptrollerLens;\\n}\\n\\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\\n mapping(address => uint256) public supplyCaps;\\n}\\n\\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\\n /// @notice AccessControlManager address\\n address internal accessControl;\\n\\n /// @notice True if a certain action is paused on a certain market\\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\\n}\\n\\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\\n mapping(address => uint256) public venusBorrowSpeeds;\\n\\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\\n mapping(address => uint256) public venusSupplySpeeds;\\n}\\n\\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n mapping(address => mapping(address => bool)) public approvedDelegates;\\n}\\n\\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\\n mapping(address => bool) public isForcedLiquidationEnabled;\\n}\\n\\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\\n }\\n\\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\\n // facet addresses\\n address[] internal _facetAddresses;\\n}\\n\\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\\n /// @notice Prime token address\\n IPrime public prime;\\n}\\n\\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\\n}\\n\\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\\n /// @notice The XVS token contract address\\n address internal xvs;\\n\\n /// @notice The XVS vToken contract address\\n address internal xvsVToken;\\n}\\n\",\"keccak256\":\"0x06608bb502e91c33fda8c0dd88cc79a49a078fab521bc27d10fc3a69c1da55f4\"},\"contracts/Comptroller/Diamond/facets/FacetBase.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { IVAIVault } from \\\"../../../Comptroller/ComptrollerInterface.sol\\\";\\nimport { ComptrollerV16Storage } from \\\"../../../Comptroller/ComptrollerStorage.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\nimport { SafeBEP20, IBEP20 } from \\\"../../../Utils/SafeBEP20.sol\\\";\\n\\n/**\\n * @title FacetBase\\n * @author Venus\\n * @notice This facet contract contains functions related to access and checks\\n */\\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\\n using SafeBEP20 for IBEP20;\\n\\n /// @notice The initial Venus index for a market\\n uint224 public constant venusInitialIndex = 1e36;\\n // closeFactorMantissa must be strictly greater than this value\\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\\n // closeFactorMantissa must not exceed this value\\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\\n // No collateralFactorMantissa may exceed this value\\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\\n\\n /// @notice Emitted when an account enters a market\\n event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n /// @notice Emitted when XVS is distributed to VAI Vault\\n event DistributedVAIVaultVenus(uint256 amount);\\n\\n /// @notice Reverts if the protocol is paused\\n function checkProtocolPauseState() internal view {\\n require(!protocolPaused, \\\"protocol is paused\\\");\\n }\\n\\n /// @notice Reverts if a certain action is paused on a market\\n function checkActionPauseState(address market, Action action) internal view {\\n require(!actionPaused(market, action), \\\"action is paused\\\");\\n }\\n\\n /// @notice Reverts if the caller is not admin\\n function ensureAdmin() internal view {\\n require(msg.sender == admin, \\\"only admin can\\\");\\n }\\n\\n /// @notice Checks the passed address is nonzero\\n function ensureNonzeroAddress(address someone) internal pure {\\n require(someone != address(0), \\\"can't be zero address\\\");\\n }\\n\\n /// @notice Reverts if the market is not listed\\n function ensureListed(Market storage market) internal view {\\n require(market.isListed, \\\"market not listed\\\");\\n }\\n\\n /// @notice Reverts if the caller is neither admin nor the passed address\\n function ensureAdminOr(address privilegedAddress) internal view {\\n require(msg.sender == admin || msg.sender == privilegedAddress, \\\"access denied\\\");\\n }\\n\\n /// @notice Checks the caller is allowed to call the specified fuction\\n function ensureAllowed(string memory functionSig) internal view {\\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \\\"access denied\\\");\\n }\\n\\n /**\\n * @notice Checks if a certain action is paused on a market\\n * @param action Action id\\n * @param market vToken address\\n */\\n function actionPaused(address market, Action action) public view returns (bool) {\\n return _actionPaused[market][uint256(action)];\\n }\\n\\n /**\\n * @notice Get the latest block number\\n */\\n function getBlockNumber() internal view returns (uint256) {\\n return block.number;\\n }\\n\\n /**\\n * @notice Get the latest block number with the safe32 check\\n */\\n function getBlockNumberAsUint32() internal view returns (uint32) {\\n return safe32(getBlockNumber(), \\\"block # > 32 bits\\\");\\n }\\n\\n /**\\n * @notice Transfer XVS to VAI Vault\\n */\\n function releaseToVault() internal {\\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\\n return;\\n }\\n\\n IBEP20 xvs_ = IBEP20(xvs);\\n\\n uint256 xvsBalance = xvs_.balanceOf(address(this));\\n if (xvsBalance == 0) {\\n return;\\n }\\n\\n uint256 actualAmount;\\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\\n // releaseAmount = venusVAIVaultRate * deltaBlocks\\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\\n\\n if (xvsBalance >= releaseAmount_) {\\n actualAmount = releaseAmount_;\\n } else {\\n actualAmount = xvsBalance;\\n }\\n\\n if (actualAmount < minReleaseAmount) {\\n return;\\n }\\n\\n releaseStartBlock = getBlockNumber();\\n\\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\\n emit DistributedVAIVaultVenus(actualAmount);\\n\\n IVAIVault(vaiVaultAddress).updatePendingRewards();\\n }\\n\\n /**\\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n * @param vTokenModify The market to hypothetically redeem/borrow in\\n * @param account The account to determine liquidity for\\n * @param redeemTokens The number of tokens to hypothetically redeem\\n * @param borrowAmount The amount of underlying to hypothetically borrow\\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n * without calculating accumulated interest.\\n * @return (possible error code,\\n hypothetical account liquidity in excess of collateral requirements,\\n * hypothetical account shortfall below collateral requirements)\\n */\\n function getHypotheticalAccountLiquidityInternal(\\n address account,\\n VToken vTokenModify,\\n uint256 redeemTokens,\\n uint256 borrowAmount\\n ) internal view returns (Error, uint256, uint256) {\\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\\n address(this),\\n account,\\n vTokenModify,\\n redeemTokens,\\n borrowAmount\\n );\\n return (Error(err), liquidity, shortfall);\\n }\\n\\n /**\\n * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n * @param vToken The market to enter\\n * @param borrower The address of the account to modify\\n * @return Success indicator for whether the market was entered\\n */\\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n Market storage marketToJoin = markets[address(vToken)];\\n ensureListed(marketToJoin);\\n if (marketToJoin.accountMembership[borrower]) {\\n // already joined\\n return Error.NO_ERROR;\\n }\\n // survived the gauntlet, add to list\\n // NOTE: we store these somewhat redundantly as a significant optimization\\n // this avoids having to iterate through the list for the most common use cases\\n // that is, only when we need to perform liquidity checks\\n // and not whenever we want to check if an account is in a particular market\\n marketToJoin.accountMembership[borrower] = true;\\n accountAssets[borrower].push(vToken);\\n\\n emit MarketEntered(vToken, borrower);\\n\\n return Error.NO_ERROR;\\n }\\n\\n /**\\n * @notice Checks for the user is allowed to redeem tokens\\n * @param vToken Address of the market\\n * @param redeemer Address of the user\\n * @param redeemTokens Amount of tokens to redeem\\n * @return Success indicator for redeem is allowed or not\\n */\\n function redeemAllowedInternal(\\n address vToken,\\n address redeemer,\\n uint256 redeemTokens\\n ) internal view returns (uint256) {\\n ensureListed(markets[vToken]);\\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n if (!markets[vToken].accountMembership[redeemer]) {\\n return uint256(Error.NO_ERROR);\\n }\\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\\n redeemer,\\n VToken(vToken),\\n redeemTokens,\\n 0\\n );\\n if (err != Error.NO_ERROR) {\\n return uint256(err);\\n }\\n if (shortfall != 0) {\\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\\n }\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Returns the XVS address\\n * @return The address of XVS token\\n */\\n function getXVSAddress() external view returns (address) {\\n return xvs;\\n }\\n}\\n\",\"keccak256\":\"0x3a015aa01706f07dd76caa6531bef30a70b5de6ac91a79c825cfef9ac2648b83\"},\"contracts/Comptroller/Diamond/facets/SetterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { ISetterFacet } from \\\"../interfaces/ISetterFacet.sol\\\";\\nimport { PriceOracle } from \\\"../../../Oracle/PriceOracle.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"../../ComptrollerLensInterface.sol\\\";\\nimport { VAIControllerInterface } from \\\"../../../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { FacetBase } from \\\"./FacetBase.sol\\\";\\nimport { IPrime } from \\\"../../../Tokens/Prime/IPrime.sol\\\";\\n\\n/**\\n * @title SetterFacet\\n * @author Venus\\n * @dev This facet contains all the setters for the states\\n * @notice This facet contract contains all the configurational setter functions\\n */\\ncontract SetterFacet is ISetterFacet, FacetBase {\\n /// @notice Emitted when close factor is changed by admin\\n event NewCloseFactor(uint256 oldCloseFactorMantissa, uint256 newCloseFactorMantissa);\\n\\n /// @notice Emitted when a collateral factor is changed by admin\\n event NewCollateralFactor(\\n VToken indexed vToken,\\n uint256 oldCollateralFactorMantissa,\\n uint256 newCollateralFactorMantissa\\n );\\n\\n /// @notice Emitted when liquidation incentive is changed by admin\\n event NewLiquidationIncentive(uint256 oldLiquidationIncentiveMantissa, uint256 newLiquidationIncentiveMantissa);\\n\\n /// @notice Emitted when price oracle is changed\\n event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle);\\n\\n /// @notice Emitted when borrow cap for a vToken is changed\\n event NewBorrowCap(VToken indexed vToken, uint256 newBorrowCap);\\n\\n /// @notice Emitted when VAIController is changed\\n event NewVAIController(VAIControllerInterface oldVAIController, VAIControllerInterface newVAIController);\\n\\n /// @notice Emitted when VAI mint rate is changed by admin\\n event NewVAIMintRate(uint256 oldVAIMintRate, uint256 newVAIMintRate);\\n\\n /// @notice Emitted when protocol state is changed by admin\\n event ActionProtocolPaused(bool state);\\n\\n /// @notice Emitted when treasury guardian is changed\\n event NewTreasuryGuardian(address oldTreasuryGuardian, address newTreasuryGuardian);\\n\\n /// @notice Emitted when treasury address is changed\\n event NewTreasuryAddress(address oldTreasuryAddress, address newTreasuryAddress);\\n\\n /// @notice Emitted when treasury percent is changed\\n event NewTreasuryPercent(uint256 oldTreasuryPercent, uint256 newTreasuryPercent);\\n\\n /// @notice Emitted when liquidator adress is changed\\n event NewLiquidatorContract(address oldLiquidatorContract, address newLiquidatorContract);\\n\\n /// @notice Emitted when ComptrollerLens address is changed\\n event NewComptrollerLens(address oldComptrollerLens, address newComptrollerLens);\\n\\n /// @notice Emitted when supply cap for a vToken is changed\\n event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /// @notice Emitted when pause guardian is changed\\n event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian);\\n\\n /// @notice Emitted when an action is paused on a market\\n event ActionPausedMarket(VToken indexed vToken, Action indexed action, bool pauseState);\\n\\n /// @notice Emitted when VAI Vault info is changed\\n event NewVAIVaultInfo(address indexed vault_, uint256 releaseStartBlock_, uint256 releaseInterval_);\\n\\n /// @notice Emitted when Venus VAI Vault rate is changed\\n event NewVenusVAIVaultRate(uint256 oldVenusVAIVaultRate, uint256 newVenusVAIVaultRate);\\n\\n /// @notice Emitted when prime token contract address is changed\\n event NewPrimeToken(IPrime oldPrimeToken, IPrime newPrimeToken);\\n\\n /// @notice Emitted when forced liquidation is enabled or disabled for all users in a market\\n event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);\\n\\n /// @notice Emitted when forced liquidation is enabled or disabled for a user borrowing in a market\\n event IsForcedLiquidationEnabledForUserUpdated(address indexed borrower, address indexed vToken, bool enable);\\n\\n /// @notice Emitted when XVS token address is changed\\n event NewXVSToken(address indexed oldXVS, address indexed newXVS);\\n\\n /// @notice Emitted when XVS vToken address is changed\\n event NewXVSVToken(address indexed oldXVSVToken, address indexed newXVSVToken);\\n\\n /**\\n * @notice Compare two addresses to ensure they are different\\n * @param oldAddress The original address to compare\\n * @param newAddress The new address to compare\\n */\\n modifier compareAddress(address oldAddress, address newAddress) {\\n require(oldAddress != newAddress, \\\"old address is same as new address\\\");\\n _;\\n }\\n\\n /**\\n * @notice Compare two values to ensure they are different\\n * @param oldValue The original value to compare\\n * @param newValue The new value to compare\\n */\\n modifier compareValue(uint256 oldValue, uint256 newValue) {\\n require(oldValue != newValue, \\\"old value is same as new value\\\");\\n _;\\n }\\n\\n /**\\n * @notice Sets a new price oracle for the comptroller\\n * @dev Allows the contract admin to set a new price oracle used by the Comptroller\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setPriceOracle(\\n PriceOracle newOracle\\n ) external compareAddress(address(oracle), address(newOracle)) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(address(newOracle));\\n\\n // Track the old oracle for the comptroller\\n PriceOracle oldOracle = oracle;\\n\\n // Set comptroller's oracle to newOracle\\n oracle = newOracle;\\n\\n // Emit NewPriceOracle(oldOracle, newOracle)\\n emit NewPriceOracle(oldOracle, newOracle);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the closeFactor used when liquidating borrows\\n * @dev Allows the contract admin to set the closeFactor used to liquidate borrows\\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n * @return uint256 0=success, otherwise will revert\\n */\\n function _setCloseFactor(\\n uint256 newCloseFactorMantissa\\n ) external compareValue(closeFactorMantissa, newCloseFactorMantissa) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n\\n Exp memory newCloseFactorExp = Exp({ mantissa: newCloseFactorMantissa });\\n\\n //-- Check close factor <= 0.9\\n Exp memory highLimit = Exp({ mantissa: closeFactorMaxMantissa });\\n //-- Check close factor >= 0.05\\n Exp memory lowLimit = Exp({ mantissa: closeFactorMinMantissa });\\n\\n if (lessThanExp(highLimit, newCloseFactorExp) || greaterThanExp(lowLimit, newCloseFactorExp)) {\\n return fail(Error.INVALID_CLOSE_FACTOR, FailureInfo.SET_CLOSE_FACTOR_VALIDATION);\\n }\\n\\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n closeFactorMantissa = newCloseFactorMantissa;\\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the address of the access control of this contract\\n * @dev Allows the contract admin to set the address of access control of this contract\\n * @param newAccessControlAddress New address for the access control\\n * @return uint256 0=success, otherwise will revert\\n */\\n function _setAccessControl(\\n address newAccessControlAddress\\n ) external compareAddress(accessControl, newAccessControlAddress) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(newAccessControlAddress);\\n\\n address oldAccessControlAddress = accessControl;\\n\\n accessControl = newAccessControlAddress;\\n emit NewAccessControl(oldAccessControlAddress, newAccessControlAddress);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets the collateralFactor for a market\\n * @dev Allows a privileged role to set the collateralFactorMantissa\\n * @param vToken The market to set the factor on\\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\\n */\\n function _setCollateralFactor(\\n VToken vToken,\\n uint256 newCollateralFactorMantissa\\n )\\n external\\n compareValue(markets[address(vToken)].collateralFactorMantissa, newCollateralFactorMantissa)\\n returns (uint256)\\n {\\n // Check caller is allowed by access control manager\\n ensureAllowed(\\\"_setCollateralFactor(address,uint256)\\\");\\n ensureNonzeroAddress(address(vToken));\\n\\n // Verify market is listed\\n Market storage market = markets[address(vToken)];\\n ensureListed(market);\\n\\n Exp memory newCollateralFactorExp = Exp({ mantissa: newCollateralFactorMantissa });\\n\\n //-- Check collateral factor <= 0.9\\n Exp memory highLimit = Exp({ mantissa: collateralFactorMaxMantissa });\\n if (lessThanExp(highLimit, newCollateralFactorExp)) {\\n return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION);\\n }\\n\\n // If collateral factor != 0, fail if price == 0\\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(vToken) == 0) {\\n return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE);\\n }\\n\\n // Set market's collateral factor to new collateral factor, remember old value\\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n market.collateralFactorMantissa = newCollateralFactorMantissa;\\n\\n // Emit event with asset, old collateral factor, and new collateral factor\\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets liquidationIncentive\\n * @dev Allows a privileged role to set the liquidationIncentiveMantissa\\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\\n */\\n function _setLiquidationIncentive(\\n uint256 newLiquidationIncentiveMantissa\\n ) external compareValue(liquidationIncentiveMantissa, newLiquidationIncentiveMantissa) returns (uint256) {\\n ensureAllowed(\\\"_setLiquidationIncentive(uint256)\\\");\\n\\n require(newLiquidationIncentiveMantissa >= 1e18, \\\"incentive < 1e18\\\");\\n\\n // Save current value for use in log\\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n // Set liquidation incentive to new incentive\\n liquidationIncentiveMantissa = newLiquidationIncentiveMantissa;\\n\\n // Emit event with old incentive, new incentive\\n emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Update the address of the liquidator contract\\n * @dev Allows the contract admin to update the address of liquidator contract\\n * @param newLiquidatorContract_ The new address of the liquidator contract\\n */\\n function _setLiquidatorContract(\\n address newLiquidatorContract_\\n ) external compareAddress(liquidatorContract, newLiquidatorContract_) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(newLiquidatorContract_);\\n address oldLiquidatorContract = liquidatorContract;\\n liquidatorContract = newLiquidatorContract_;\\n emit NewLiquidatorContract(oldLiquidatorContract, newLiquidatorContract_);\\n }\\n\\n /**\\n * @notice Admin function to change the Pause Guardian\\n * @dev Allows the contract admin to change the Pause Guardian\\n * @param newPauseGuardian The address of the new Pause Guardian\\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\\n */\\n function _setPauseGuardian(\\n address newPauseGuardian\\n ) external compareAddress(pauseGuardian, newPauseGuardian) returns (uint256) {\\n ensureAdmin();\\n ensureNonzeroAddress(newPauseGuardian);\\n\\n // Save current value for inclusion in log\\n address oldPauseGuardian = pauseGuardian;\\n // Store pauseGuardian with value newPauseGuardian\\n pauseGuardian = newPauseGuardian;\\n\\n // Emit NewPauseGuardian(OldPauseGuardian, NewPauseGuardian)\\n emit NewPauseGuardian(oldPauseGuardian, newPauseGuardian);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\\n * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed\\n * @param vTokens The addresses of the markets (tokens) to change the borrow caps for\\n * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed\\n */\\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n ensureAllowed(\\\"_setMarketBorrowCaps(address[],uint256[])\\\");\\n\\n uint256 numMarkets = vTokens.length;\\n uint256 numBorrowCaps = newBorrowCaps.length;\\n\\n require(numMarkets != 0 && numMarkets == numBorrowCaps, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numMarkets; ++i) {\\n borrowCaps[address(vTokens[i])] = newBorrowCaps[i];\\n emit NewBorrowCap(vTokens[i], newBorrowCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\\n * @dev Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\\n * @param vTokens The addresses of the markets (tokens) to change the supply caps for\\n * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\\n */\\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n ensureAllowed(\\\"_setMarketSupplyCaps(address[],uint256[])\\\");\\n\\n uint256 numMarkets = vTokens.length;\\n uint256 numSupplyCaps = newSupplyCaps.length;\\n\\n require(numMarkets != 0 && numMarkets == numSupplyCaps, \\\"invalid input\\\");\\n\\n for (uint256 i; i < numMarkets; ++i) {\\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n }\\n }\\n\\n /**\\n * @notice Set whole protocol pause/unpause state\\n * @dev Allows a privileged role to pause/unpause protocol\\n * @param state The new state (true=paused, false=unpaused)\\n * @return bool The updated state of the protocol\\n */\\n function _setProtocolPaused(bool state) external returns (bool) {\\n ensureAllowed(\\\"_setProtocolPaused(bool)\\\");\\n\\n protocolPaused = state;\\n emit ActionProtocolPaused(state);\\n return state;\\n }\\n\\n /**\\n * @notice Pause/unpause certain actions\\n * @dev Allows a privileged role to pause/unpause the protocol action state\\n * @param markets_ Markets to pause/unpause the actions on\\n * @param actions_ List of action ids to pause/unpause\\n * @param paused_ The new paused state (true=paused, false=unpaused)\\n */\\n function _setActionsPaused(address[] calldata markets_, Action[] calldata actions_, bool paused_) external {\\n ensureAllowed(\\\"_setActionsPaused(address[],uint8[],bool)\\\");\\n\\n uint256 numMarkets = markets_.length;\\n uint256 numActions = actions_.length;\\n for (uint256 marketIdx; marketIdx < numMarkets; ++marketIdx) {\\n for (uint256 actionIdx; actionIdx < numActions; ++actionIdx) {\\n setActionPausedInternal(markets_[marketIdx], actions_[actionIdx], paused_);\\n }\\n }\\n }\\n\\n /**\\n * @dev Pause/unpause an action on a market\\n * @param market Market to pause/unpause the action on\\n * @param action Action id to pause/unpause\\n * @param paused The new paused state (true=paused, false=unpaused)\\n */\\n function setActionPausedInternal(address market, Action action, bool paused) internal {\\n ensureListed(markets[market]);\\n _actionPaused[market][uint256(action)] = paused;\\n emit ActionPausedMarket(VToken(market), action, paused);\\n }\\n\\n /**\\n * @notice Sets a new VAI controller\\n * @dev Admin function to set a new VAI controller\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setVAIController(\\n VAIControllerInterface vaiController_\\n ) external compareAddress(address(vaiController), address(vaiController_)) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n ensureNonzeroAddress(address(vaiController_));\\n\\n VAIControllerInterface oldVaiController = vaiController;\\n vaiController = vaiController_;\\n emit NewVAIController(oldVaiController, vaiController_);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the VAI mint rate\\n * @param newVAIMintRate The new VAI mint rate to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setVAIMintRate(\\n uint256 newVAIMintRate\\n ) external compareValue(vaiMintRate, newVAIMintRate) returns (uint256) {\\n // Check caller is admin\\n ensureAdmin();\\n uint256 oldVAIMintRate = vaiMintRate;\\n vaiMintRate = newVAIMintRate;\\n emit NewVAIMintRate(oldVAIMintRate, newVAIMintRate);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the minted VAI amount of the `owner`\\n * @param owner The address of the account to set\\n * @param amount The amount of VAI to set to the account\\n * @return The number of minted VAI by `owner`\\n */\\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256) {\\n checkProtocolPauseState();\\n\\n // Pausing is a very serious situation - we revert to sound the alarms\\n require(!mintVAIGuardianPaused && !repayVAIGuardianPaused, \\\"VAI is paused\\\");\\n // Check caller is vaiController\\n if (msg.sender != address(vaiController)) {\\n return fail(Error.REJECTION, FailureInfo.SET_MINTED_VAI_REJECTION);\\n }\\n mintedVAIs[owner] = amount;\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the treasury data.\\n * @param newTreasuryGuardian The new address of the treasury guardian to be set\\n * @param newTreasuryAddress The new address of the treasury to be set\\n * @param newTreasuryPercent The new treasury percent to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setTreasuryData(\\n address newTreasuryGuardian,\\n address newTreasuryAddress,\\n uint256 newTreasuryPercent\\n ) external returns (uint256) {\\n // Check caller is admin\\n ensureAdminOr(treasuryGuardian);\\n\\n require(newTreasuryPercent < 1e18, \\\"percent >= 100%\\\");\\n ensureNonzeroAddress(newTreasuryGuardian);\\n ensureNonzeroAddress(newTreasuryAddress);\\n\\n address oldTreasuryGuardian = treasuryGuardian;\\n address oldTreasuryAddress = treasuryAddress;\\n uint256 oldTreasuryPercent = treasuryPercent;\\n\\n treasuryGuardian = newTreasuryGuardian;\\n treasuryAddress = newTreasuryAddress;\\n treasuryPercent = newTreasuryPercent;\\n\\n emit NewTreasuryGuardian(oldTreasuryGuardian, newTreasuryGuardian);\\n emit NewTreasuryAddress(oldTreasuryAddress, newTreasuryAddress);\\n emit NewTreasuryPercent(oldTreasuryPercent, newTreasuryPercent);\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /*** Venus Distribution ***/\\n\\n /**\\n * @dev Set ComptrollerLens contract address\\n * @param comptrollerLens_ The new ComptrollerLens contract address to be set\\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setComptrollerLens(\\n ComptrollerLensInterface comptrollerLens_\\n ) external compareAddress(address(comptrollerLens), address(comptrollerLens_)) returns (uint256) {\\n ensureAdmin();\\n ensureNonzeroAddress(address(comptrollerLens_));\\n address oldComptrollerLens = address(comptrollerLens);\\n comptrollerLens = comptrollerLens_;\\n emit NewComptrollerLens(oldComptrollerLens, address(comptrollerLens));\\n\\n return uint256(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Set the amount of XVS distributed per block to VAI Vault\\n * @param venusVAIVaultRate_ The amount of XVS wei per block to distribute to VAI Vault\\n */\\n function _setVenusVAIVaultRate(\\n uint256 venusVAIVaultRate_\\n ) external compareValue(venusVAIVaultRate, venusVAIVaultRate_) {\\n ensureAdmin();\\n if (vaiVaultAddress != address(0)) {\\n releaseToVault();\\n }\\n uint256 oldVenusVAIVaultRate = venusVAIVaultRate;\\n venusVAIVaultRate = venusVAIVaultRate_;\\n emit NewVenusVAIVaultRate(oldVenusVAIVaultRate, venusVAIVaultRate_);\\n }\\n\\n /**\\n * @notice Set the VAI Vault infos\\n * @param vault_ The address of the VAI Vault\\n * @param releaseStartBlock_ The start block of release to VAI Vault\\n * @param minReleaseAmount_ The minimum release amount to VAI Vault\\n */\\n function _setVAIVaultInfo(\\n address vault_,\\n uint256 releaseStartBlock_,\\n uint256 minReleaseAmount_\\n ) external compareAddress(vaiVaultAddress, vault_) {\\n ensureAdmin();\\n ensureNonzeroAddress(vault_);\\n if (vaiVaultAddress != address(0)) {\\n releaseToVault();\\n }\\n\\n vaiVaultAddress = vault_;\\n releaseStartBlock = releaseStartBlock_;\\n minReleaseAmount = minReleaseAmount_;\\n emit NewVAIVaultInfo(vault_, releaseStartBlock_, minReleaseAmount_);\\n }\\n\\n /**\\n * @notice Sets the prime token contract for the comptroller\\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\\n */\\n function _setPrimeToken(IPrime _prime) external returns (uint) {\\n ensureAdmin();\\n ensureNonzeroAddress(address(_prime));\\n\\n IPrime oldPrime = prime;\\n prime = _prime;\\n emit NewPrimeToken(oldPrime, _prime);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /** @notice Enables forced liquidations for a market. If forced liquidation is enabled,\\n * borrows in the market may be liquidated regardless of the account liquidity\\n * @dev Allows a privileged role to set enable/disable forced liquidations\\n * @param vTokenBorrowed Borrowed vToken\\n * @param enable Whether to enable forced liquidations\\n */\\n function _setForcedLiquidation(address vTokenBorrowed, bool enable) external {\\n ensureAllowed(\\\"_setForcedLiquidation(address,bool)\\\");\\n if (vTokenBorrowed != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n isForcedLiquidationEnabled[vTokenBorrowed] = enable;\\n emit IsForcedLiquidationEnabledUpdated(vTokenBorrowed, enable);\\n }\\n\\n /**\\n * @notice Enables forced liquidations for user's borrows in a certain market. If forced\\n * liquidation is enabled, user's borrows in the market may be liquidated regardless of\\n * the account liquidity. Forced liquidation may be enabled for a user even if it is not\\n * enabled for the entire market.\\n * @param borrower The address of the borrower\\n * @param vTokenBorrowed Borrowed vToken\\n * @param enable Whether to enable forced liquidations\\n */\\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external {\\n ensureAllowed(\\\"_setForcedLiquidationForUser(address,address,bool)\\\");\\n if (vTokenBorrowed != address(vaiController)) {\\n ensureListed(markets[vTokenBorrowed]);\\n }\\n isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed] = enable;\\n emit IsForcedLiquidationEnabledForUserUpdated(borrower, vTokenBorrowed, enable);\\n }\\n\\n /**\\n * @notice Set the address of the XVS token\\n * @param xvs_ The address of the XVS token\\n */\\n function _setXVSToken(address xvs_) external {\\n ensureAdmin();\\n ensureNonzeroAddress(xvs_);\\n\\n emit NewXVSToken(xvs, xvs_);\\n xvs = xvs_;\\n }\\n\\n /**\\n * @notice Set the address of the XVS vToken\\n * @param xvsVToken_ The address of the XVS vToken\\n */\\n function _setXVSVToken(address xvsVToken_) external {\\n ensureAdmin();\\n ensureNonzeroAddress(xvsVToken_);\\n\\n address underlying = VToken(xvsVToken_).underlying();\\n require(underlying == xvs, \\\"invalid xvs vtoken address\\\");\\n\\n emit NewXVSVToken(xvsVToken, xvsVToken_);\\n xvsVToken = xvsVToken_;\\n }\\n}\\n\",\"keccak256\":\"0xb40b72d16ab7fe6b247c6482893e93d7cf343b21cef7c066f48ef56bec42e192\"},\"contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\n\\npragma solidity 0.5.16;\\n\\nimport { PriceOracle } from \\\"../../../Oracle/PriceOracle.sol\\\";\\nimport { VToken } from \\\"../../../Tokens/VTokens/VToken.sol\\\";\\nimport { ComptrollerTypes } from \\\"../../ComptrollerStorage.sol\\\";\\nimport { VAIControllerInterface } from \\\"../../../Tokens/VAI/VAIControllerInterface.sol\\\";\\nimport { ComptrollerLensInterface } from \\\"../../../Comptroller/ComptrollerLensInterface.sol\\\";\\nimport { IPrime } from \\\"../../../Tokens/Prime/IPrime.sol\\\";\\n\\ninterface ISetterFacet {\\n function _setPriceOracle(PriceOracle newOracle) external returns (uint256);\\n\\n function _setCloseFactor(uint256 newCloseFactorMantissa) external returns (uint256);\\n\\n function _setAccessControl(address newAccessControlAddress) external returns (uint256);\\n\\n function _setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256);\\n\\n function _setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256);\\n\\n function _setLiquidatorContract(address newLiquidatorContract_) external;\\n\\n function _setPauseGuardian(address newPauseGuardian) external returns (uint256);\\n\\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external;\\n\\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external;\\n\\n function _setProtocolPaused(bool state) external returns (bool);\\n\\n function _setActionsPaused(\\n address[] calldata markets,\\n ComptrollerTypes.Action[] calldata actions,\\n bool paused\\n ) external;\\n\\n function _setVAIController(VAIControllerInterface vaiController_) external returns (uint256);\\n\\n function _setVAIMintRate(uint256 newVAIMintRate) external returns (uint256);\\n\\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256);\\n\\n function _setTreasuryData(\\n address newTreasuryGuardian,\\n address newTreasuryAddress,\\n uint256 newTreasuryPercent\\n ) external returns (uint256);\\n\\n function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint256);\\n\\n function _setVenusVAIVaultRate(uint256 venusVAIVaultRate_) external;\\n\\n function _setVAIVaultInfo(address vault_, uint256 releaseStartBlock_, uint256 minReleaseAmount_) external;\\n\\n function _setForcedLiquidation(address vToken, bool enable) external;\\n\\n function _setPrimeToken(IPrime _prime) external returns (uint);\\n\\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external;\\n\\n function _setXVSToken(address xvs_) external;\\n\\n function _setXVSVToken(address xvsVToken_) external;\\n}\\n\",\"keccak256\":\"0x8d1e48445f80aca8652555a50783e3fb908351040abf45a90f1ce557abcabede\"},\"contracts/InterestRateModels/InterestRateModel.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Venus's InterestRateModel Interface\\n * @author Venus\\n */\\ncontract InterestRateModel {\\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\\n bool public constant isInterestRateModel = true;\\n\\n /**\\n * @notice Calculates the current borrow interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\\n\\n /**\\n * @notice Calculates the current supply interest rate per block\\n * @param cash The total amount of cash the market has\\n * @param borrows The total amount of borrows the market has outstanding\\n * @param reserves The total amnount of reserves the market has\\n * @param reserveFactorMantissa The current reserve factor the market has\\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\\n */\\n function getSupplyRate(\\n uint cash,\\n uint borrows,\\n uint reserves,\\n uint reserveFactorMantissa\\n ) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x7896290ed5d98f1b744676c0cf5cb0bc656befdd8a79ae4cd2d9f90d83aaa52d\"},\"contracts/Oracle/PriceOracle.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../Tokens/VTokens/VToken.sol\\\";\\n\\ncontract PriceOracle {\\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\\n bool public constant isPriceOracle = true;\\n\\n /**\\n * @notice Get the underlying price of a vToken asset\\n * @param vToken The vToken to get the underlying price of\\n * @return The underlying asset price mantissa (scaled by 1e18).\\n * Zero means the price is unavailable.\\n */\\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\\n}\\n\",\"keccak256\":\"0x0f68d0e07decba8fb9a77df1659170f310b487cc0b650f53ca6aa55ed62b28de\"},\"contracts/Tokens/EIP20Interface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title BEP 20 Token Standard Interface\\n * https://eips.ethereum.org/EIPS/eip-20\\n */\\ninterface EIP20Interface {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transfer(address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return success whether or not the transfer succeeded\\n */\\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return success whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x7e89ffa9c0d432c4db8bd5388ff68e33934dcdb1d038d74bbed3b2fdae3eb532\"},\"contracts/Tokens/EIP20NonStandardInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title EIP20NonStandardInterface\\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\\n */\\ninterface EIP20NonStandardInterface {\\n /**\\n * @notice Get the total number of tokens in circulation\\n * @return The supply of tokens\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @notice Gets the balance of the specified address\\n * @param owner The address from which the balance will be retrieved\\n * @return balance of the owner\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transfer(address dst, uint256 amount) external;\\n\\n ///\\n /// !!!!!!!!!!!!!!\\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\\n /// !!!!!!!!!!!!!!\\n ///\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n */\\n function transferFrom(address src, address dst, uint256 amount) external;\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved\\n * @return success Whether or not the approval succeeded\\n */\\n function approve(address spender, uint256 amount) external returns (bool success);\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return remaining The number of tokens allowed to be spent\\n */\\n function allowance(address owner, address spender) external view returns (uint256 remaining);\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n}\\n\",\"keccak256\":\"0x05a3a7d5ab47de3964c95d706dcc18fe7583b1d064dbb74808c0f2774f347afa\"},\"contracts/Tokens/Prime/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.5.16;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n /**\\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n * @param user the account address whose balance was updated\\n */\\n function xvsUpdated(address user) external;\\n\\n /**\\n * @notice accrues interest and updates score for an user for a specific market\\n * @param user the account address for which to accrue interest and update score\\n * @param market the market for which to accrue interest and update score\\n */\\n function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n /**\\n * @notice Distributes income from market since last distribution\\n * @param vToken the market for which to distribute the income\\n */\\n function accrueInterest(address vToken) external;\\n\\n /**\\n * @notice Returns if user is a prime holder\\n * @param isPrimeHolder returns if the user is a prime holder\\n */\\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\\n}\\n\",\"keccak256\":\"0x58861c0c05b8757f1a5d50b107eff479c8680878e6aa51bc93af420caf73f500\"},\"contracts/Tokens/VAI/VAIControllerInterface.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport { VTokenInterface } from \\\"../VTokens/VTokenInterfaces.sol\\\";\\n\\ncontract VAIControllerInterface {\\n function mintVAI(uint256 mintVAIAmount) external returns (uint256);\\n\\n function repayVAI(uint256 amount) external returns (uint256, uint256);\\n\\n function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256);\\n\\n function liquidateVAI(\\n address borrower,\\n uint256 repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint256, uint256);\\n\\n function getMintableVAI(address minter) external view returns (uint256, uint256);\\n\\n function getVAIAddress() external view returns (address);\\n\\n function getVAIRepayAmount(address account) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x1f020ff46cb0efa0ebf563f449fd4d8aa1c8b8ed53c46860d71a08548d7fdfaa\"},\"contracts/Tokens/VTokens/VToken.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../Utils/ErrorReporter.sol\\\";\\nimport \\\"../../Utils/Exponential.sol\\\";\\nimport \\\"../../Tokens/EIP20Interface.sol\\\";\\nimport \\\"../../Tokens/EIP20NonStandardInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\nimport \\\"./VTokenInterfaces.sol\\\";\\nimport { IAccessControlManagerV5 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\\\";\\n\\n/**\\n * @title Venus's vToken Contract\\n * @notice Abstract base for vTokens\\n * @author Venus\\n */\\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\\n struct MintLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint mintTokens;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n uint actualMintAmount;\\n }\\n\\n struct RedeemLocalVars {\\n MathError mathErr;\\n uint exchangeRateMantissa;\\n uint redeemTokens;\\n uint redeemAmount;\\n uint totalSupplyNew;\\n uint accountTokensNew;\\n }\\n\\n struct BorrowLocalVars {\\n MathError mathErr;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n }\\n\\n struct RepayBorrowLocalVars {\\n Error err;\\n MathError mathErr;\\n uint repayAmount;\\n uint borrowerIndex;\\n uint accountBorrows;\\n uint accountBorrowsNew;\\n uint totalBorrowsNew;\\n uint actualRepayAmount;\\n }\\n\\n /*** Reentrancy Guard ***/\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n */\\n modifier nonReentrant() {\\n require(_notEntered, \\\"re-entered\\\");\\n _notEntered = false;\\n _;\\n _notEntered = true; // get a gas-refund post-Istanbul\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Transfer `amount` tokens from `src` to `dst`\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param amount The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n // @custom:event Emits Transfer event\\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Approve `spender` to transfer up to `amount` from `src`\\n * @dev This will overwrite the approval amount for `spender`\\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n * @param spender The address of the account which may transfer tokens\\n * @param amount The number of tokens that are approved (-1 means infinite)\\n * @return Whether or not the approval succeeded\\n */\\n // @custom:event Emits Approval event on successful approve\\n function approve(address spender, uint256 amount) external returns (bool) {\\n transferAllowances[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Get the underlying balance of the `owner`\\n * @dev This also accrues interest in a transaction\\n * @param owner The address of the account to query\\n * @return The amount of underlying owned by `owner`\\n */\\n function balanceOfUnderlying(address owner) external returns (uint) {\\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\\n ensureNoMathError(mErr);\\n return balance;\\n }\\n\\n /**\\n * @notice Returns the current total borrows plus accrued interest\\n * @return The total borrows with interest\\n */\\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return totalBorrows;\\n }\\n\\n /**\\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n * @param account The address whose balance should be calculated after updating borrowIndex\\n * @return The calculated balance\\n */\\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return borrowBalanceStored(account);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Will fail unless called by another vToken during the process of liquidation.\\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits Transfer event\\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\\n }\\n\\n /**\\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\\n * @param newPendingAdmin New pending admin.\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\\n // Check caller = admin\\n ensureAdmin(msg.sender);\\n\\n // Save current value, if any, for inclusion in log\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store pendingAdmin with value newPendingAdmin\\n pendingAdmin = newPendingAdmin;\\n\\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\\n * @dev Admin function for pending admin to accept role and update admin\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewAdmin event on successful acceptance\\n // @custom:event Emits NewPendingAdmin event with null new pending admin\\n function _acceptAdmin() external returns (uint) {\\n // Check caller is pendingAdmin\\n if (msg.sender != pendingAdmin) {\\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\\n }\\n\\n // Save current values for inclusion in log\\n address oldAdmin = admin;\\n address oldPendingAdmin = pendingAdmin;\\n\\n // Store admin with value pendingAdmin\\n admin = pendingAdmin;\\n\\n // Clear the pending value\\n pendingAdmin = address(0);\\n\\n emit NewAdmin(oldAdmin, admin);\\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\\n * @dev Governor function to accrue interest and set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewReserveFactor event\\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_setReserveFactor(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\\n }\\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\\n return _setReserveFactorFresh(newReserveFactorMantissa_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract\\n * @dev Admin function to set the access control address\\n * @param newAccessControlManagerAddress New address for the access control\\n * @return uint 0=success, otherwise will revert\\n */\\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ensureNonZeroAddress(newAccessControlManagerAddress);\\n\\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\\n accessControlManager = newAccessControlManagerAddress;\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\\n * @param reduceAmount_ Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits ReservesReduced event\\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\\n ensureAllowed(\\\"_reduceReserves(uint256)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // If reserves were reduced in accrueInterest\\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\\n return _reduceReservesFresh(reduceAmount_);\\n }\\n\\n /**\\n * @notice Get the current allowance from `owner` for `spender`\\n * @param owner The address of the account which owns the tokens to be spent\\n * @param spender The address of the account which may transfer tokens\\n * @return The number of tokens allowed to be spent (-1 means infinite)\\n */\\n function allowance(address owner, address spender) external view returns (uint256) {\\n return transferAllowances[owner][spender];\\n }\\n\\n /**\\n * @notice Get the token balance of the `owner`\\n * @param owner The address of the account to query\\n * @return The number of tokens owned by `owner`\\n */\\n function balanceOf(address owner) external view returns (uint256) {\\n return accountTokens[owner];\\n }\\n\\n /**\\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n * @param account Address of the account to snapshot\\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\\n */\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\\n uint vTokenBalance = accountTokens[account];\\n uint borrowBalance;\\n uint exchangeRateMantissa;\\n\\n MathError mErr;\\n\\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (mErr != MathError.NO_ERROR) {\\n return (uint(Error.MATH_ERROR), 0, 0, 0);\\n }\\n\\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block supply interest rate for this vToken\\n * @return The supply interest rate per block, scaled by 1e18\\n */\\n function supplyRatePerBlock() external view returns (uint) {\\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\\n }\\n\\n /**\\n * @notice Returns the current per-block borrow interest rate for this vToken\\n * @return The borrow interest rate per block, scaled by 1e18\\n */\\n function borrowRatePerBlock() external view returns (uint) {\\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\\n }\\n\\n /**\\n * @notice Get cash balance of this vToken in the underlying asset\\n * @return The quantity of underlying asset owned by this contract\\n */\\n function getCash() external view returns (uint) {\\n return getCashPrior();\\n }\\n\\n /**\\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\\n * @param newReduceReservesBlockDelta_ block difference value\\n */\\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\\n require(newReduceReservesBlockDelta_ > 0, \\\"Invalid Input\\\");\\n ensureAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\\n }\\n\\n /**\\n * @notice Sets protocol share reserve contract address\\n * @param protcolShareReserve_ The address of protocol share reserve contract\\n */\\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n ensureNonZeroAddress(protcolShareReserve_);\\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\\n protocolShareReserve = protcolShareReserve_;\\n }\\n\\n /**\\n * @notice Initialize the money market\\n * @param comptroller_ The address of the Comptroller\\n * @param interestRateModel_ The address of the interest rate model\\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n * @param name_ EIP-20 name of this token\\n * @param symbol_ EIP-20 symbol of this token\\n * @param decimals_ EIP-20 decimal precision of this token\\n */\\n function initialize(\\n ComptrollerInterface comptroller_,\\n InterestRateModel interestRateModel_,\\n uint initialExchangeRateMantissa_,\\n string memory name_,\\n string memory symbol_,\\n uint8 decimals_\\n ) public {\\n ensureAdmin(msg.sender);\\n require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n // Set initial exchange rate\\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n // Set the comptroller\\n uint err = _setComptroller(comptroller_);\\n require(err == uint(Error.NO_ERROR), \\\"setting comptroller failed\\\");\\n\\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\\n accrualBlockNumber = block.number;\\n borrowIndex = mantissaOne;\\n\\n // Set the interest rate model (depends on block number / borrow index)\\n err = _setInterestRateModelFresh(interestRateModel_);\\n require(err == uint(Error.NO_ERROR), \\\"setting interest rate model failed\\\");\\n\\n name = name_;\\n symbol = symbol_;\\n decimals = decimals_;\\n\\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n _notEntered = true;\\n }\\n\\n /**\\n * @notice Accrue interest then return the up-to-date exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateCurrent() public nonReentrant returns (uint) {\\n require(accrueInterest() == uint(Error.NO_ERROR), \\\"accrue interest failed\\\");\\n return exchangeRateStored();\\n }\\n\\n /**\\n * @notice Applies accrued interest to total borrows and reserves\\n * @dev This calculates interest accrued from the last checkpointed block\\n * up to the current block and writes new checkpoint to storage and\\n * reduce spread reserves to protocol share reserve\\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\\n */\\n // @custom:event Emits AccrueInterest event\\n function accrueInterest() public returns (uint) {\\n /* Remember the initial block number */\\n uint currentBlockNumber = block.number;\\n uint accrualBlockNumberPrior = accrualBlockNumber;\\n\\n /* Short-circuit accumulating 0 interest */\\n if (accrualBlockNumberPrior == currentBlockNumber) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n /* Read the previous values out of storage */\\n uint cashPrior = getCashPrior();\\n uint borrowsPrior = totalBorrows;\\n uint reservesPrior = totalReserves;\\n uint borrowIndexPrior = borrowIndex;\\n\\n /* Calculate the current borrow interest rate */\\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\\n require(borrowRateMantissa <= borrowRateMaxMantissa, \\\"borrow rate is absurdly high\\\");\\n\\n /* Calculate the number of blocks elapsed since the last accrual */\\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\\n ensureNoMathError(mathErr);\\n\\n /*\\n * Calculate the interest accumulated into borrows and reserves and the new index:\\n * simpleInterestFactor = borrowRate * blockDelta\\n * interestAccumulated = simpleInterestFactor * totalBorrows\\n * totalBorrowsNew = interestAccumulated + totalBorrows\\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n */\\n\\n Exp memory simpleInterestFactor;\\n uint interestAccumulated;\\n uint totalBorrowsNew;\\n uint totalReservesNew;\\n uint borrowIndexNew;\\n\\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\\n Exp({ mantissa: reserveFactorMantissa }),\\n interestAccumulated,\\n reservesPrior\\n );\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n if (mathErr != MathError.NO_ERROR) {\\n return\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n uint(mathErr)\\n );\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accrualBlockNumber = currentBlockNumber;\\n borrowIndex = borrowIndexNew;\\n totalBorrows = totalBorrowsNew;\\n totalReserves = totalReservesNew;\\n\\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\\n ensureNoMathError(mathErr);\\n if (blockDelta >= reduceReservesBlockDelta) {\\n reduceReservesBlockNumber = currentBlockNumber;\\n if (cashPrior < totalReservesNew) {\\n _reduceReservesFresh(cashPrior);\\n } else {\\n _reduceReservesFresh(totalReservesNew);\\n }\\n }\\n\\n /* We emit an AccrueInterest event */\\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new comptroller for the market\\n * @dev Admin function to set a new comptroller\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // @custom:event Emits NewComptroller event\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\\n // Check caller is admin\\n ensureAdmin(msg.sender);\\n\\n ComptrollerInterface oldComptroller = comptroller;\\n // Ensure invoke comptroller.isComptroller() returns true\\n require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n // Set market's comptroller to newComptroller\\n comptroller = newComptroller;\\n\\n // Emit NewComptroller(oldComptroller, newComptroller)\\n emit NewComptroller(oldComptroller, newComptroller);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n * @dev Governance function to accrue interest and update the interest rate model\\n * @param newInterestRateModel_ The new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\\n ensureAllowed(\\\"_setInterestRateModel(address)\\\");\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\\n }\\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\\n return _setInterestRateModelFresh(newInterestRateModel_);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the VToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStored() public view returns (uint) {\\n (MathError err, uint result) = exchangeRateStoredInternal();\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return The calculated balance\\n */\\n function borrowBalanceStored(address account) public view returns (uint) {\\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\\n ensureNoMathError(err);\\n return result;\\n }\\n\\n /**\\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\\n * @dev Called by both `transfer` and `transferFrom` internally\\n * @param spender The address of the account performing the transfer\\n * @param src The address of the source account\\n * @param dst The address of the destination account\\n * @param tokens The number of tokens to transfer\\n * @return Whether or not the transfer succeeded\\n */\\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\\n /* Fail if transfer not allowed */\\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Do not allow self-transfers */\\n if (src == dst) {\\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n /* Get the allowance, infinite for the account owner */\\n uint startingAllowance = 0;\\n if (spender == src) {\\n startingAllowance = uint(-1);\\n } else {\\n startingAllowance = transferAllowances[src][spender];\\n }\\n\\n /* Do the calculations, checking for {under,over}flow */\\n MathError mathErr;\\n uint allowanceNew;\\n uint srvTokensNew;\\n uint dstTokensNew;\\n\\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\\n }\\n\\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\\n }\\n\\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n accountTokens[src] = srvTokensNew;\\n accountTokens[dst] = dstTokensNew;\\n\\n /* Eat some of the allowance (if necessary) */\\n if (startingAllowance != uint(-1)) {\\n transferAllowances[src][spender] = allowanceNew;\\n }\\n\\n /* We emit a Transfer event */\\n emit Transfer(src, dst, tokens);\\n\\n comptroller.transferVerify(address(this), src, dst, tokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintFresh(msg.sender, mintAmount);\\n }\\n\\n /**\\n * @notice User supplies assets into the market and receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param minter The address of the account which is supplying the assets\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the minter and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[minter] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[minter] = vars.accountTokensNew;\\n\\n /* We emit a Mint event, and a Transfer event */\\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), minter, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param receiver The address of the account which is receiving the vTokens\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\\n }\\n\\n /**\\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param payer The address of the account which is paying the underlying token\\n * @param receiver The address of the account which is receiving vToken\\n * @param mintAmount The amount of the underlying asset to supply\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\\n */\\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\\n ensureNonZeroAddress(receiver);\\n /* Fail if mint not allowed */\\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\\n }\\n\\n MintLocalVars memory vars;\\n\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call `doTransferIn` for the payer and the mintAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n * side-effects occurred. The function returns the amount actually transferred,\\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n * of cash.\\n */\\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\\n\\n /*\\n * We get the current exchange rate and calculate the number of vTokens to be minted:\\n * mintTokens = actualMintAmount / exchangeRate\\n */\\n\\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\\n vars.actualMintAmount,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n /*\\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\\n * totalSupplyNew = totalSupply + mintTokens\\n * accountTokensNew = accountTokens[receiver] + mintTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[receiver] = vars.accountTokensNew;\\n\\n /* We emit a MintBehalf event, and a Transfer event */\\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\\n emit Transfer(address(this), receiver, vars.mintTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\\n\\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokens The number of vTokens to redeem into underlying\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokens\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\\n }\\n\\n /**\\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens, if called by a delegate\\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function redeemUnderlyingInternal(\\n address redeemer,\\n address payable receiver,\\n uint redeemAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\\n }\\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\\n }\\n\\n /**\\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\\n * @dev Assumes interest has already been accrued up to the current block\\n * @param redeemer The address of the account which is redeeming the tokens\\n * @param receiver The receiver of the tokens\\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n // solhint-disable-next-line code-complexity\\n function redeemFresh(\\n address redeemer,\\n address payable receiver,\\n uint redeemTokensIn,\\n uint redeemAmountIn\\n ) internal returns (uint) {\\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n RedeemLocalVars memory vars;\\n\\n /* exchangeRate = invoke Exchange Rate Stored() */\\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\\n ensureNoMathError(vars.mathErr);\\n\\n /* If redeemTokensIn > 0: */\\n if (redeemTokensIn > 0) {\\n /*\\n * We calculate the exchange rate and the amount of underlying to be redeemed:\\n * redeemTokens = redeemTokensIn\\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\\n */\\n vars.redeemTokens = redeemTokensIn;\\n\\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\\n Exp({ mantissa: vars.exchangeRateMantissa }),\\n redeemTokensIn\\n );\\n ensureNoMathError(vars.mathErr);\\n } else {\\n /*\\n * We get the current exchange rate and calculate the amount to be redeemed:\\n * redeemTokens = redeemAmountIn / exchangeRate\\n * redeemAmount = redeemAmountIn\\n */\\n\\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\\n redeemAmountIn,\\n Exp({ mantissa: vars.exchangeRateMantissa })\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n vars.redeemAmount = redeemAmountIn;\\n }\\n\\n /* Fail if redeem not allowed */\\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /*\\n * We calculate the new total supply and redeemer balance, checking for underflow:\\n * totalSupplyNew = totalSupply - redeemTokens\\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\\n */\\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\\n ensureNoMathError(vars.mathErr);\\n\\n /* Fail gracefully if protocol has insufficient cash */\\n if (getCashPrior() < vars.redeemAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write previously calculated values into storage */\\n totalSupply = vars.totalSupplyNew;\\n accountTokens[redeemer] = vars.accountTokensNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the redeemAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken has redeemAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n\\n uint feeAmount;\\n uint remainedAmount;\\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\\n (vars.mathErr, feeAmount) = mulUInt(\\n vars.redeemAmount,\\n IComptroller(address(comptroller)).treasuryPercent()\\n );\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\\n\\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\\n } else {\\n remainedAmount = vars.redeemAmount;\\n }\\n\\n doTransferOut(receiver, remainedAmount);\\n\\n /* We emit a Transfer event, and a Redeem event */\\n emit Transfer(redeemer, address(this), vars.redeemTokens);\\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function borrowInternal(\\n address borrower,\\n address payable receiver,\\n uint borrowAmount\\n ) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\\n }\\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\\n return borrowFresh(borrower, receiver, borrowAmount);\\n }\\n\\n /**\\n * @notice Receiver gets the borrow on behalf of the borrower address\\n * @dev Before calling this function, ensure that the interest has been accrued\\n * @param borrower The borrower, on behalf of whom to borrow\\n * @param receiver The account that would receive the funds (can be the same as the borrower)\\n * @param borrowAmount The amount of the underlying asset to borrow\\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\\n */\\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\\n /* Revert if borrow not allowed */\\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\\n if (allowed != 0) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n revert(\\\"math error\\\");\\n }\\n\\n /* Revert if protocol has insufficient underlying cash */\\n if (getCashPrior() < borrowAmount) {\\n revert(\\\"math error\\\");\\n }\\n\\n BorrowLocalVars memory vars;\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on overflow:\\n * accountBorrowsNew = accountBorrows + borrowAmount\\n * totalBorrowsNew = totalBorrows + borrowAmount\\n */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /*\\n * We invoke doTransferOut for the receiver and the borrowAmount.\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken borrowAmount less of cash.\\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n */\\n doTransferOut(receiver, borrowAmount);\\n\\n /* We emit a Borrow event */\\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sender repays their own borrow\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n }\\n\\n /**\\n * @notice Sender repays a borrow belonging to another borrowing account\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\\n }\\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\\n }\\n\\n /**\\n * @notice Borrows are repaid by another user (possibly the borrower).\\n * @param payer The account paying off the borrow\\n * @param borrower The account with the debt being payed off\\n * @param repayAmount The amount of undelrying tokens being returned\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\\n /* Fail if repayBorrow not allowed */\\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\\n if (allowed != 0) {\\n return (\\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\\n 0\\n );\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\\n }\\n\\n RepayBorrowLocalVars memory vars;\\n\\n /* We remember the original borrowerIndex for verification purposes */\\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\\n\\n /* We fetch the amount the borrower owes, with accumulated interest */\\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\\n if (vars.mathErr != MathError.NO_ERROR) {\\n return (\\n failOpaque(\\n Error.MATH_ERROR,\\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n uint(vars.mathErr)\\n ),\\n 0\\n );\\n }\\n\\n /* If repayAmount == -1, repayAmount = accountBorrows */\\n if (repayAmount == uint(-1)) {\\n vars.repayAmount = vars.accountBorrows;\\n } else {\\n vars.repayAmount = repayAmount;\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the payer and the repayAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional repayAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\\n\\n /*\\n * We calculate the new borrower and total borrow balances, failing on underflow:\\n * accountBorrowsNew = accountBorrows - actualRepayAmount\\n * totalBorrowsNew = totalBorrows - actualRepayAmount\\n */\\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\\n ensureNoMathError(vars.mathErr);\\n\\n /* We write the previously calculated values into storage */\\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\\n accountBorrows[borrower].interestIndex = borrowIndex;\\n totalBorrows = vars.totalBorrowsNew;\\n\\n /* We emit a RepayBorrow event */\\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\\n\\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\\n }\\n\\n /**\\n * @notice The sender liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n function liquidateBorrowInternal(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal nonReentrant returns (uint, uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\\n }\\n\\n error = vTokenCollateral.accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\\n }\\n\\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\\n }\\n\\n /**\\n * @notice The liquidator liquidates the borrowers collateral.\\n * The collateral seized is transferred to the liquidator.\\n * @param borrower The borrower of this vToken to be liquidated\\n * @param liquidator The address repaying the borrow and seizing collateral\\n * @param vTokenCollateral The market in which to seize collateral from the borrower\\n * @param repayAmount The amount of the underlying borrowed asset to repay\\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\\n */\\n // solhint-disable-next-line code-complexity\\n function liquidateBorrowFresh(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) internal returns (uint, uint) {\\n /* Fail if liquidate not allowed */\\n uint allowed = comptroller.liquidateBorrowAllowed(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n repayAmount\\n );\\n if (allowed != 0) {\\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\\n }\\n\\n /* Verify market's block number equals current block number */\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Verify vTokenCollateral market's block number equals current block number */\\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\\n }\\n\\n /* Fail if repayAmount = 0 */\\n if (repayAmount == 0) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\\n }\\n\\n /* Fail if repayAmount = -1 */\\n if (repayAmount == uint(-1)) {\\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\\n }\\n\\n /* Fail if repayBorrow fails */\\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\\n if (repayBorrowError != uint(Error.NO_ERROR)) {\\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We calculate the number of collateral tokens that will be seized */\\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n address(this),\\n address(vTokenCollateral),\\n actualRepayAmount\\n );\\n require(amountSeizeError == uint(Error.NO_ERROR), \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n /* Revert if borrower collateral token balance < seizeTokens */\\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\\n uint seizeError;\\n if (address(vTokenCollateral) == address(this)) {\\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\\n } else {\\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n }\\n\\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\\n require(seizeError == uint(Error.NO_ERROR), \\\"token seizure failed\\\");\\n\\n /* We emit a LiquidateBorrow event */\\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.liquidateBorrowVerify(\\n address(this),\\n address(vTokenCollateral),\\n liquidator,\\n borrower,\\n actualRepayAmount,\\n seizeTokens\\n );\\n\\n return (uint(Error.NO_ERROR), actualRepayAmount);\\n }\\n\\n /**\\n * @notice Transfers collateral tokens (this market) to the liquidator.\\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\\n * @param liquidator The account receiving seized collateral\\n * @param borrower The account having collateral seized\\n * @param seizeTokens The number of vTokens to seize\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function seizeInternal(\\n address seizerToken,\\n address liquidator,\\n address borrower,\\n uint seizeTokens\\n ) internal returns (uint) {\\n /* Fail if seize not allowed */\\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n if (allowed != 0) {\\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\\n }\\n\\n /* Fail if borrower = liquidator */\\n if (borrower == liquidator) {\\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\\n }\\n\\n MathError mathErr;\\n uint borrowerTokensNew;\\n uint liquidatorTokensNew;\\n\\n /*\\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n */\\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\\n }\\n\\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\\n if (mathErr != MathError.NO_ERROR) {\\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /* We write the previously calculated values into storage */\\n accountTokens[borrower] = borrowerTokensNew;\\n accountTokens[liquidator] = liquidatorTokensNew;\\n\\n /* Emit a Transfer event */\\n emit Transfer(borrower, liquidator, seizeTokens);\\n\\n /* We call the defense and prime accrue interest hook */\\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\\n * @dev Governance function to set a new reserve factor\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\\n // Verify market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\\n }\\n\\n // Check newReserveFactor \\u2264 maxReserveFactor\\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\\n }\\n\\n uint oldReserveFactorMantissa = reserveFactorMantissa;\\n reserveFactorMantissa = newReserveFactorMantissa;\\n\\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\\n * @param addAmount Amount of addition to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\\n uint error = accrueInterest();\\n if (error != uint(Error.NO_ERROR)) {\\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\\n }\\n\\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\\n (error, ) = _addReservesFresh(addAmount);\\n return error;\\n }\\n\\n /**\\n * @notice Add reserves by transferring from caller\\n * @dev Requires fresh interest accrual\\n * @param addAmount Amount of addition to reserves\\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\\n */\\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\\n // totalReserves + actualAddAmount\\n uint totalReservesNew;\\n uint actualAddAmount;\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n /*\\n * We call doTransferIn for the caller and the addAmount\\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\\n * On success, the vToken holds an additional addAmount of cash.\\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n * it returns the amount actually transferred, in case of a fee.\\n */\\n\\n actualAddAmount = doTransferIn(msg.sender, addAmount);\\n\\n totalReservesNew = totalReserves + actualAddAmount;\\n\\n /* Revert on overflow */\\n require(totalReservesNew >= totalReserves, \\\"add reserves unexpected overflow\\\");\\n\\n // Store reserves[n+1] = reserves[n] + actualAddAmount\\n totalReserves = totalReservesNew;\\n\\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n /* Return (NO_ERROR, actualAddAmount) */\\n return (uint(Error.NO_ERROR), actualAddAmount);\\n }\\n\\n /**\\n * @notice Reduces reserves by transferring to protocol share reserve contract\\n * @dev Requires fresh interest accrual\\n * @param reduceAmount Amount of reduction to reserves\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\\n if (reduceAmount == 0) {\\n return uint(Error.NO_ERROR);\\n }\\n\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\\n }\\n\\n // Fail gracefully if protocol has insufficient underlying cash\\n if (getCashPrior() < reduceAmount) {\\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\\n }\\n\\n // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n if (reduceAmount > totalReserves) {\\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\\n }\\n\\n /////////////////////////\\n // EFFECTS & INTERACTIONS\\n // (No safe failures beyond this point)\\n\\n // totalReserves - reduceAmount\\n uint totalReservesNew = totalReserves - reduceAmount;\\n\\n // Store reserves[n+1] = reserves[n] - reduceAmount\\n totalReserves = totalReservesNew;\\n\\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n doTransferOut(protocolShareReserve, reduceAmount);\\n\\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\\n address(comptroller),\\n underlying,\\n IProtocolShareReserveV5.IncomeType.SPREAD\\n );\\n\\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /**\\n * @notice updates the interest rate model (requires fresh interest accrual)\\n * @dev Governance function to update the interest rate model\\n * @param newInterestRateModel the new interest rate model to use\\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\\n */\\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\\n // Used to store old model for use in the event that is emitted on success\\n InterestRateModel oldInterestRateModel;\\n // We fail gracefully unless market's block number equals current block number\\n if (accrualBlockNumber != block.number) {\\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\\n }\\n\\n // Track the market's current interest rate model\\n oldInterestRateModel = interestRateModel;\\n\\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n // Set the interest rate model to newInterestRateModel\\n interestRateModel = newInterestRateModel;\\n\\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n\\n return uint(Error.NO_ERROR);\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\\n * This may revert due to insufficient balance or insufficient allowance.\\n */\\n function doTransferIn(address from, uint amount) internal returns (uint);\\n\\n /**\\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\\n */\\n function doTransferOut(address payable to, uint amount) internal;\\n\\n /**\\n * @notice Return the borrow balance of account based on stored data\\n * @param account The address whose balance should be calculated\\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\\n */\\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\\n /* Note: we do not assert that the market is up to date */\\n MathError mathErr;\\n uint principalTimesIndex;\\n uint result;\\n\\n /* Get borrowBalance and borrowIndex */\\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\\n\\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n */\\n if (borrowSnapshot.principal == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n /* Calculate new borrow balance using the interest index:\\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n */\\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, result);\\n }\\n\\n /**\\n * @notice Calculates the exchange rate from the underlying to the vToken\\n * @dev This function does not accrue interest before calculating the exchange rate\\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\\n */\\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\\n uint _totalSupply = totalSupply;\\n if (_totalSupply == 0) {\\n /*\\n * If there are no tokens minted:\\n * exchangeRate = initialExchangeRate\\n */\\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\\n } else {\\n /*\\n * Otherwise:\\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\\n */\\n uint totalCash = getCashPrior();\\n uint cashPlusBorrowsMinusReserves;\\n Exp memory exchangeRate;\\n MathError mathErr;\\n\\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\\n if (mathErr != MathError.NO_ERROR) {\\n return (mathErr, 0);\\n }\\n\\n return (MathError.NO_ERROR, exchangeRate.mantissa);\\n }\\n }\\n\\n function ensureAllowed(string memory functionSig) private view {\\n require(\\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\\n \\\"access denied\\\"\\n );\\n }\\n\\n function ensureAdmin(address caller_) private view {\\n require(caller_ == admin, \\\"Unauthorized\\\");\\n }\\n\\n function ensureNoMathError(MathError mErr) private pure {\\n require(mErr == MathError.NO_ERROR, \\\"math error\\\");\\n }\\n\\n function ensureNonZeroAddress(address address_) private pure {\\n require(address_ != address(0), \\\"zero address\\\");\\n }\\n\\n /*** Safe Token ***/\\n\\n /**\\n * @notice Gets balance of this contract in terms of the underlying\\n * @dev This excludes the value of the current message, if any\\n * @return The quantity of underlying owned by this contract\\n */\\n function getCashPrior() internal view returns (uint);\\n}\\n\",\"keccak256\":\"0xfdbcdbd6cab4aeba2c06f39adbfbd8e42a3e50d02aed628c2d76b97659d84b68\"},\"contracts/Tokens/VTokens/VTokenInterfaces.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"../../Comptroller/ComptrollerInterface.sol\\\";\\nimport \\\"../../InterestRateModels/InterestRateModel.sol\\\";\\n\\ninterface IProtocolShareReserveV5 {\\n enum IncomeType {\\n SPREAD,\\n LIQUIDATION\\n }\\n\\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\\n}\\n\\ncontract VTokenStorageBase {\\n /**\\n * @notice Container for borrow balance information\\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n */\\n struct BorrowSnapshot {\\n uint principal;\\n uint interestIndex;\\n }\\n\\n /**\\n * @dev Guard variable for re-entrancy checks\\n */\\n bool internal _notEntered;\\n\\n /**\\n * @notice EIP-20 token name for this token\\n */\\n string public name;\\n\\n /**\\n * @notice EIP-20 token symbol for this token\\n */\\n string public symbol;\\n\\n /**\\n * @notice EIP-20 token decimals for this token\\n */\\n uint8 public decimals;\\n\\n /**\\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\\n */\\n\\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\\n\\n /**\\n * @notice Maximum fraction of interest that can be set aside for reserves\\n */\\n uint internal constant reserveFactorMaxMantissa = 1e18;\\n\\n /**\\n * @notice Administrator for this contract\\n */\\n address payable public admin;\\n\\n /**\\n * @notice Pending administrator for this contract\\n */\\n address payable public pendingAdmin;\\n\\n /**\\n * @notice Contract which oversees inter-vToken operations\\n */\\n ComptrollerInterface public comptroller;\\n\\n /**\\n * @notice Model which tells what the current interest rate should be\\n */\\n InterestRateModel public interestRateModel;\\n\\n /**\\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n */\\n uint internal initialExchangeRateMantissa;\\n\\n /**\\n * @notice Fraction of interest currently set aside for reserves\\n */\\n uint public reserveFactorMantissa;\\n\\n /**\\n * @notice Block number that interest was last accrued at\\n */\\n uint public accrualBlockNumber;\\n\\n /**\\n * @notice Accumulator of the total earned interest rate since the opening of the market\\n */\\n uint public borrowIndex;\\n\\n /**\\n * @notice Total amount of outstanding borrows of the underlying in this market\\n */\\n uint public totalBorrows;\\n\\n /**\\n * @notice Total amount of reserves of the underlying held in this market\\n */\\n uint public totalReserves;\\n\\n /**\\n * @notice Total number of tokens in circulation\\n */\\n uint public totalSupply;\\n\\n /**\\n * @notice Official record of token balances for each account\\n */\\n mapping(address => uint) internal accountTokens;\\n\\n /**\\n * @notice Approved token transfer amounts on behalf of others\\n */\\n mapping(address => mapping(address => uint)) internal transferAllowances;\\n\\n /**\\n * @notice Mapping of account addresses to outstanding borrow balances\\n */\\n mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n /**\\n * @notice Underlying asset for this VToken\\n */\\n address public underlying;\\n\\n /**\\n * @notice Implementation address for this contract\\n */\\n address public implementation;\\n\\n /**\\n * @notice delta block after which reserves will be reduced\\n */\\n uint public reduceReservesBlockDelta;\\n\\n /**\\n * @notice last block number at which reserves were reduced\\n */\\n uint public reduceReservesBlockNumber;\\n\\n /**\\n * @notice address of protocol share reserve contract\\n */\\n address payable public protocolShareReserve;\\n\\n /**\\n * @notice address of accessControlManager\\n */\\n\\n address public accessControlManager;\\n}\\n\\ncontract VTokenStorage is VTokenStorageBase {\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\\ncontract VTokenInterface is VTokenStorage {\\n /**\\n * @notice Indicator that this is a vToken contract (for inspection)\\n */\\n bool public constant isVToken = true;\\n\\n /*** Market Events ***/\\n\\n /**\\n * @notice Event emitted when interest is accrued\\n */\\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when tokens are minted\\n */\\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are minted behalf by payer to receiver\\n */\\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed\\n */\\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\\n\\n /**\\n * @notice Event emitted when tokens are redeemed and fee is transferred\\n */\\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\\n\\n /**\\n * @notice Event emitted when underlying is borrowed\\n */\\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is repaid\\n */\\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\\n\\n /**\\n * @notice Event emitted when a borrow is liquidated\\n */\\n event LiquidateBorrow(\\n address liquidator,\\n address borrower,\\n uint repayAmount,\\n address vTokenCollateral,\\n uint seizeTokens\\n );\\n\\n /*** Admin Events ***/\\n\\n /**\\n * @notice Event emitted when pendingAdmin is changed\\n */\\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\\n\\n /**\\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\\n */\\n event NewAdmin(address oldAdmin, address newAdmin);\\n\\n /**\\n * @notice Event emitted when comptroller is changed\\n */\\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\\n\\n /**\\n * @notice Event emitted when interestRateModel is changed\\n */\\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\\n\\n /**\\n * @notice Event emitted when the reserve factor is changed\\n */\\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\\n\\n /**\\n * @notice Event emitted when the reserves are added\\n */\\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\\n\\n /**\\n * @notice Event emitted when the reserves are reduced\\n */\\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\\n\\n /**\\n * @notice EIP20 Transfer event\\n */\\n event Transfer(address indexed from, address indexed to, uint amount);\\n\\n /**\\n * @notice EIP20 Approval event\\n */\\n event Approval(address indexed owner, address indexed spender, uint amount);\\n\\n /**\\n * @notice Event emitted when block delta for reduce reserves get updated\\n */\\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\\n\\n /**\\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\\n */\\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n /**\\n * @notice Failure event\\n */\\n event Failure(uint error, uint info, uint detail);\\n\\n /// @notice Emitted when access control address is changed by admin\\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\\n\\n /*** User Interface ***/\\n\\n function transfer(address dst, uint amount) external returns (bool);\\n\\n function transferFrom(address src, address dst, uint amount) external returns (bool);\\n\\n function approve(address spender, uint amount) external returns (bool);\\n\\n function balanceOfUnderlying(address owner) external returns (uint);\\n\\n function totalBorrowsCurrent() external returns (uint);\\n\\n function borrowBalanceCurrent(address account) external returns (uint);\\n\\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _acceptAdmin() external returns (uint);\\n\\n /*** Admin Function ***/\\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\\n\\n /*** Admin Function ***/\\n function _reduceReserves(uint reduceAmount) external returns (uint);\\n\\n function balanceOf(address owner) external view returns (uint);\\n\\n function allowance(address owner, address spender) external view returns (uint);\\n\\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\\n\\n function borrowRatePerBlock() external view returns (uint);\\n\\n function supplyRatePerBlock() external view returns (uint);\\n\\n function getCash() external view returns (uint);\\n\\n function exchangeRateCurrent() public returns (uint);\\n\\n function accrueInterest() public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\\n\\n /*** Admin Function ***/\\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\\n\\n function borrowBalanceStored(address account) public view returns (uint);\\n\\n function exchangeRateStored() public view returns (uint);\\n}\\n\\ncontract VBep20Interface {\\n /*** User Interface ***/\\n\\n function mint(uint mintAmount) external returns (uint);\\n\\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n function redeem(uint redeemTokens) external returns (uint);\\n\\n function redeemUnderlying(uint redeemAmount) external returns (uint);\\n\\n function borrow(uint borrowAmount) external returns (uint);\\n\\n function repayBorrow(uint repayAmount) external returns (uint);\\n\\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\\n\\n function liquidateBorrow(\\n address borrower,\\n uint repayAmount,\\n VTokenInterface vTokenCollateral\\n ) external returns (uint);\\n\\n /*** Admin Functions ***/\\n\\n function _addReserves(uint addAmount) external returns (uint);\\n}\\n\\ncontract VDelegatorInterface {\\n /**\\n * @notice Emitted when implementation is changed\\n */\\n event NewImplementation(address oldImplementation, address newImplementation);\\n\\n /**\\n * @notice Called by the admin to update the implementation of the delegator\\n * @param implementation_ The address of the new implementation for delegation\\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\\n */\\n function _setImplementation(\\n address implementation_,\\n bool allowResign,\\n bytes memory becomeImplementationData\\n ) public;\\n}\\n\\ncontract VDelegateInterface {\\n /**\\n * @notice Called by the delegator on a delegate to initialize it for duty\\n * @dev Should revert if any issues arise which make it unfit for delegation\\n * @param data The encoded bytes data for any initialization\\n */\\n function _becomeImplementation(bytes memory data) public;\\n\\n /**\\n * @notice Called by the delegator on a delegate to forfeit its responsibility\\n */\\n function _resignImplementation() public;\\n}\\n\",\"keccak256\":\"0x2f12533847458414b423cc85677489709d772bec4e48933ae983d6861202a41b\"},\"contracts/Utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n codehash := extcodehash(account)\\n }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n *\\n * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n // solium-disable-next-line security/no-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x3c2ef780599a2ae6913282b982633f07e405a4a9c8511590df571e2b773aef9d\"},\"contracts/Utils/CarefulMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Careful Math\\n * @author Venus\\n * @notice Derived from OpenZeppelin's SafeMath library\\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\\n */\\ncontract CarefulMath {\\n /**\\n * @dev Possible error codes that we can return\\n */\\n enum MathError {\\n NO_ERROR,\\n DIVISION_BY_ZERO,\\n INTEGER_OVERFLOW,\\n INTEGER_UNDERFLOW\\n }\\n\\n /**\\n * @dev Multiplies two numbers, returns an error on overflow.\\n */\\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (a == 0) {\\n return (MathError.NO_ERROR, 0);\\n }\\n\\n uint c = a * b;\\n\\n if (c / a != b) {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n } else {\\n return (MathError.NO_ERROR, c);\\n }\\n }\\n\\n /**\\n * @dev Integer division of two numbers, truncating the quotient.\\n */\\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b == 0) {\\n return (MathError.DIVISION_BY_ZERO, 0);\\n }\\n\\n return (MathError.NO_ERROR, a / b);\\n }\\n\\n /**\\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\\n */\\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n if (b <= a) {\\n return (MathError.NO_ERROR, a - b);\\n } else {\\n return (MathError.INTEGER_UNDERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev Adds two numbers, returns an error on overflow.\\n */\\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\\n uint c = a + b;\\n\\n if (c >= a) {\\n return (MathError.NO_ERROR, c);\\n } else {\\n return (MathError.INTEGER_OVERFLOW, 0);\\n }\\n }\\n\\n /**\\n * @dev add a and b and then subtract c\\n */\\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\\n (MathError err0, uint sum) = addUInt(a, b);\\n\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, 0);\\n }\\n\\n return subUInt(sum, c);\\n }\\n}\\n\",\"keccak256\":\"0x5bd84fb723641b98d0559272323b90ce42595f025af89cfb214d8c064c9ee3c3\"},\"contracts/Utils/ErrorReporter.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\ncontract ComptrollerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n COMPTROLLER_MISMATCH,\\n INSUFFICIENT_SHORTFALL,\\n INSUFFICIENT_LIQUIDITY,\\n INVALID_CLOSE_FACTOR,\\n INVALID_COLLATERAL_FACTOR,\\n INVALID_LIQUIDATION_INCENTIVE,\\n MARKET_NOT_ENTERED, // no longer possible\\n MARKET_NOT_LISTED,\\n MARKET_ALREADY_LISTED,\\n MATH_ERROR,\\n NONZERO_BORROW_BALANCE,\\n PRICE_ERROR,\\n REJECTION,\\n SNAPSHOT_ERROR,\\n TOO_MANY_ASSETS,\\n TOO_MUCH_REPAY,\\n INSUFFICIENT_BALANCE_FOR_VAI,\\n MARKET_NOT_COLLATERAL\\n }\\n\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n EXIT_MARKET_BALANCE_OWED,\\n EXIT_MARKET_REJECTION,\\n SET_CLOSE_FACTOR_OWNER_CHECK,\\n SET_CLOSE_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_NO_EXISTS,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\\n SET_IMPLEMENTATION_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_PRICE_ORACLE_OWNER_CHECK,\\n SUPPORT_MARKET_EXISTS,\\n SUPPORT_MARKET_OWNER_CHECK,\\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\\n SET_VAI_MINT_RATE_CHECK,\\n SET_VAICONTROLLER_OWNER_CHECK,\\n SET_MINTED_VAI_REJECTION,\\n SET_TREASURY_OWNER_CHECK,\\n UNLIST_MARKET_NOT_LISTED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract TokenErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED,\\n BAD_INPUT,\\n COMPTROLLER_REJECTION,\\n COMPTROLLER_CALCULATION_ERROR,\\n INTEREST_RATE_MODEL_ERROR,\\n INVALID_ACCOUNT_PAIR,\\n INVALID_CLOSE_AMOUNT_REQUESTED,\\n INVALID_COLLATERAL_FACTOR,\\n MATH_ERROR,\\n MARKET_NOT_FRESH,\\n MARKET_NOT_LISTED,\\n TOKEN_INSUFFICIENT_ALLOWANCE,\\n TOKEN_INSUFFICIENT_BALANCE,\\n TOKEN_INSUFFICIENT_CASH,\\n TOKEN_TRANSFER_IN_FAILED,\\n TOKEN_TRANSFER_OUT_FAILED,\\n TOKEN_PRICE_ERROR\\n }\\n\\n /*\\n * Note: FailureInfo (but not Error) is kept in alphabetical order\\n * This is because FailureInfo grows significantly faster, and\\n * the order of Error has some meaning, while the order of FailureInfo\\n * is entirely arbitrary.\\n */\\n enum FailureInfo {\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n BORROW_ACCRUE_INTEREST_FAILED,\\n BORROW_CASH_NOT_AVAILABLE,\\n BORROW_FRESHNESS_CHECK,\\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n BORROW_MARKET_NOT_LISTED,\\n BORROW_COMPTROLLER_REJECTION,\\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n LIQUIDATE_COMPTROLLER_REJECTION,\\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n LIQUIDATE_FRESHNESS_CHECK,\\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_ACCRUE_INTEREST_FAILED,\\n MINT_COMPTROLLER_REJECTION,\\n MINT_EXCHANGE_CALCULATION_FAILED,\\n MINT_EXCHANGE_RATE_READ_FAILED,\\n MINT_FRESHNESS_CHECK,\\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n MINT_TRANSFER_IN_FAILED,\\n MINT_TRANSFER_IN_NOT_POSSIBLE,\\n REDEEM_ACCRUE_INTEREST_FAILED,\\n REDEEM_COMPTROLLER_REJECTION,\\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\\n REDEEM_EXCHANGE_RATE_READ_FAILED,\\n REDEEM_FRESHNESS_CHECK,\\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\\n REDUCE_RESERVES_ADMIN_CHECK,\\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\\n REDUCE_RESERVES_FRESH_CHECK,\\n REDUCE_RESERVES_VALIDATION,\\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_COMPTROLLER_REJECTION,\\n REPAY_BORROW_FRESHNESS_CHECK,\\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\\n SET_COLLATERAL_FACTOR_VALIDATION,\\n SET_COMPTROLLER_OWNER_CHECK,\\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\\n SET_MAX_ASSETS_OWNER_CHECK,\\n SET_ORACLE_MARKET_NOT_LISTED,\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\\n SET_RESERVE_FACTOR_ADMIN_CHECK,\\n SET_RESERVE_FACTOR_FRESH_CHECK,\\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\\n TRANSFER_COMPTROLLER_REJECTION,\\n TRANSFER_NOT_ALLOWED,\\n TRANSFER_NOT_ENOUGH,\\n TRANSFER_TOO_MUCH,\\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\\n ADD_RESERVES_FRESH_CHECK,\\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\\n REPAY_VAI_COMPTROLLER_REJECTION,\\n REPAY_VAI_FRESHNESS_CHECK,\\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\\ncontract VAIControllerErrorReporter {\\n enum Error {\\n NO_ERROR,\\n UNAUTHORIZED, // The sender is not authorized to perform this action.\\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\\n MATH_ERROR, // A math calculation error occurred.\\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\\n }\\n\\n enum FailureInfo {\\n SET_PENDING_ADMIN_OWNER_CHECK,\\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\\n SET_COMPTROLLER_OWNER_CHECK,\\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\\n VAI_MINT_REJECTION,\\n VAI_BURN_REJECTION,\\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\\n VAI_LIQUIDATE_FRESHNESS_CHECK,\\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\\n MINT_FEE_CALCULATION_FAILED,\\n SET_TREASURY_OWNER_CHECK\\n }\\n\\n /**\\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\\n **/\\n event Failure(uint error, uint info, uint detail);\\n\\n /**\\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\\n */\\n function fail(Error err, FailureInfo info) internal returns (uint) {\\n emit Failure(uint(err), uint(info), 0);\\n\\n return uint(err);\\n }\\n\\n /**\\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\\n */\\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\\n emit Failure(uint(err), uint(info), opaqueError);\\n\\n return uint(err);\\n }\\n}\\n\",\"keccak256\":\"0x4f5a41ef380336395706659e2b8f315870dcf3d617ea6f81104424500b15b1ef\"},\"contracts/Utils/Exponential.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\nimport \\\"./CarefulMath.sol\\\";\\nimport \\\"./ExponentialNoError.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Venus\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract Exponential is CarefulMath, ExponentialNoError {\\n /**\\n * @dev Creates an exponential from numerator and denominator values.\\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\\n * or if `denom` is zero.\\n */\\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\\n }\\n\\n /**\\n * @dev Adds two exponentials, returning a new exponential.\\n */\\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Subtracts two exponentials, returning a new exponential.\\n */\\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\\n\\n return (error, Exp({ mantissa: result }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, returning a new Exp.\\n */\\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(product));\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory product) = mulScalar(a, scalar);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return addUInt(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Divide an Exp by a scalar, returning a new Exp.\\n */\\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, returning a new Exp.\\n */\\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\\n /*\\n We are doing this as:\\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\\n\\n How it works:\\n Exp = a / b;\\n Scalar = s;\\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\\n */\\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n return getExp(numerator, divisor.mantissa);\\n }\\n\\n /**\\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\\n */\\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\\n if (err != MathError.NO_ERROR) {\\n return (err, 0);\\n }\\n\\n return (MathError.NO_ERROR, truncate(fraction));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials, returning a new exponential.\\n */\\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\\n if (err0 != MathError.NO_ERROR) {\\n return (err0, Exp({ mantissa: 0 }));\\n }\\n\\n // We add half the scale before dividing so that we get rounding instead of truncation.\\n // See \\\"Listing 6\\\" and text above it at https://accu.org/index.php/journals/1717\\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\\n if (err1 != MathError.NO_ERROR) {\\n return (err1, Exp({ mantissa: 0 }));\\n }\\n\\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\\n assert(err2 == MathError.NO_ERROR);\\n\\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\\n }\\n\\n /**\\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\\n */\\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\\n }\\n\\n /**\\n * @dev Multiplies three exponentials, returning a new exponential.\\n */\\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\\n (MathError err, Exp memory ab) = mulExp(a, b);\\n if (err != MathError.NO_ERROR) {\\n return (err, ab);\\n }\\n return mulExp(ab, c);\\n }\\n\\n /**\\n * @dev Divides two exponentials, returning a new exponential.\\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\\n */\\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\\n return getExp(a.mantissa, b.mantissa);\\n }\\n}\\n\",\"keccak256\":\"0x92a68e9f6de3a70b103aa0ddb68faa8e60c443b1268e03853d5054171fe8e290\"},\"contracts/Utils/ExponentialNoError.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n * `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n uint internal constant expScale = 1e18;\\n uint internal constant doubleScale = 1e36;\\n uint internal constant halfExpScale = expScale / 2;\\n uint internal constant mantissaOne = expScale;\\n\\n struct Exp {\\n uint mantissa;\\n }\\n\\n struct Double {\\n uint mantissa;\\n }\\n\\n /**\\n * @dev Truncates the given exp to a whole number value.\\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\\n */\\n function truncate(Exp memory exp) internal pure returns (uint) {\\n // Note: We are not using careful math here as we're performing a division that cannot fail\\n return exp.mantissa / expScale;\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n */\\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return truncate(product);\\n }\\n\\n /**\\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n */\\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\\n Exp memory product = mul_(a, scalar);\\n return add_(truncate(product), addend);\\n }\\n\\n /**\\n * @dev Checks if first Exp is less than second Exp.\\n */\\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa < right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp <= right Exp.\\n */\\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa <= right.mantissa;\\n }\\n\\n /**\\n * @dev Checks if left Exp > right Exp.\\n */\\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n return left.mantissa > right.mantissa;\\n }\\n\\n /**\\n * @dev returns true if Exp is exactly zero\\n */\\n function isZeroExp(Exp memory value) internal pure returns (bool) {\\n return value.mantissa == 0;\\n }\\n\\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\\n require(n < 2 ** 224, errorMessage);\\n return uint224(n);\\n }\\n\\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\\n require(n < 2 ** 32, errorMessage);\\n return uint32(n);\\n }\\n\\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n }\\n\\n function add_(uint a, uint b) internal pure returns (uint) {\\n return add_(a, b, \\\"addition overflow\\\");\\n }\\n\\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n uint c = a + b;\\n require(c >= a, errorMessage);\\n return c;\\n }\\n\\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n }\\n\\n function sub_(uint a, uint b) internal pure returns (uint) {\\n return sub_(a, b, \\\"subtraction underflow\\\");\\n }\\n\\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\\n }\\n\\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / expScale;\\n }\\n\\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\\n }\\n\\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: mul_(a.mantissa, b) });\\n }\\n\\n function mul_(uint a, Double memory b) internal pure returns (uint) {\\n return mul_(a, b.mantissa) / doubleScale;\\n }\\n\\n function mul_(uint a, uint b) internal pure returns (uint) {\\n return mul_(a, b, \\\"multiplication overflow\\\");\\n }\\n\\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n if (a == 0 || b == 0) {\\n return 0;\\n }\\n uint c = a * b;\\n require(c / a == b, errorMessage);\\n return c;\\n }\\n\\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\\n }\\n\\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\\n return Exp({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Exp memory b) internal pure returns (uint) {\\n return div_(mul_(a, expScale), b.mantissa);\\n }\\n\\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\\n }\\n\\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(a.mantissa, b) });\\n }\\n\\n function div_(uint a, Double memory b) internal pure returns (uint) {\\n return div_(mul_(a, doubleScale), b.mantissa);\\n }\\n\\n function div_(uint a, uint b) internal pure returns (uint) {\\n return div_(a, b, \\\"divide by zero\\\");\\n }\\n\\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n function fraction(uint a, uint b) internal pure returns (Double memory) {\\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\\n }\\n}\\n\",\"keccak256\":\"0x237e63d9ad2bf232d70f854b8867a465913cab4d2033d295ec7736bf618ca302\"},\"contracts/Utils/IBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {BEP20Detailed}.\\n */\\ninterface IBEP20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x839b08895eb1ad83502d3631e8e9e3a856d2a8c63c46f070d604af7b26c62c07\"},\"contracts/Utils/SafeBEP20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./SafeMath.sol\\\";\\nimport \\\"./IBEP20.sol\\\";\\nimport \\\"./Address.sol\\\";\\n\\n/**\\n * @title SafeBEP20\\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeBEP20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeBEP20: approve from non-zero to non-zero allowance\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(\\n value,\\n \\\"SafeBEP20: decreased allowance below zero\\\"\\n );\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeBEP20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeBEP20: low-level call failed\\\");\\n\\n if (returndata.length > 0) {\\n // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeBEP20: BEP20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x540ef6ddc47232a59d3ab0e95537f7a7d1c8a36f8dba315b010e60c6487bd768\"},\"contracts/Utils/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.16;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return add(a, b, \\\"SafeMath: addition overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, errorMessage);\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9431fd772ed4abc038cdfe9ce6c0066897bd1685ad45848748d1952935d5b8ef\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506130ee806100206000396000f3fe608060405234801561001057600080fd5b50600436106103f15760003560e01c80637dc0d1d011610215578063bf32442d11610125578063e37d4b79116100b8578063f445d70311610087578063f445d70314610cdf578063f519fc3014610d0d578063f851a44014610d33578063fa6331d814610d3b578063fd51a3ad14610d43576103f1565b8063e37d4b7914610c56578063e4028eee14610c7c578063e85a296014610ca8578063e875544614610cd7576103f1565b8063d24febad116100f4578063d24febad14610be4578063d3270f9914610c1a578063dce1544914610c22578063dcfbc0c714610c4e576103f1565b8063bf32442d14610ba8578063c5b4db5514610bb0578063c5f956af14610bd4578063c7ee005e14610bdc576103f1565b80639bb27d62116101a8578063b8324c7c11610177578063b8324c7c14610afe578063bb82aa5e14610b4c578063bb85745014610b54578063bbb8864a14610b7a578063bec04f7214610ba0576103f1565b80639bb27d6214610aa25780639bf34cbb14610aaa5780639cfdd9e614610ad0578063b2eafc3914610af6576103f1565b8063919a3736116101e4578063919a373614610a465780639254f5e514610a6c5780639460c8b514610a7457806394b2294b14610a9a576103f1565b80637dc0d1d0146109aa5780638a7dc165146109b25780638c1ac18a146109d85780638e8f294b146109fe576103f1565b8063425fad581161031057806352d84d1e116102a3578063607ef6c111610272578063607ef6c1146108b75780636662c7c914610975578063719f701b14610992578063765513831461099a5780637d172bd5146109a2576103f1565b806352d84d1e1461082857806355ee1fe1146108455780635dd3fc9d1461086b5780635f5af1aa14610891576103f1565b80634ef233fc116102df5780634ef233fc146106f95780634fd42e171461071f57806351a485e41461073c578063522c656b146107fa576103f1565b8063425fad58146106915780634a584432146106995780634ada90af146106bf5780634e0853db146106c7576103f1565b806326782247116103885780632ec04124116103575780632ec0412414610621578063317b0b771461063e5780634088c73e1461065b57806341a18d2c14610663576103f1565b806326782247146105145780632a6a60651461051c5780632b5d790c1461053b5780632bc7e29e146105fb576103f1565b806310b98338116103c457806310b983381461046c57806317db2163146104ae57806321af4569146104e857806324a3d6221461050c576103f1565b806302c3bcbb146103f657806304ef9d581461042e57806308e0225c146104365780630db4b4e514610464575b600080fd5b61041c6004803603602081101561040c57600080fd5b50356001600160a01b0316610d6f565b60408051918252519081900360200190f35b61041c610d81565b61041c6004803603604081101561044c57600080fd5b506001600160a01b0381358116916020013516610d87565b61041c610da4565b61049a6004803603604081101561048257600080fd5b506001600160a01b0381358116916020013516610daa565b604080519115158252519081900360200190f35b6104e6600480360360608110156104c457600080fd5b506001600160a01b038135811691602081013590911690604001351515610dca565b005b6104f0610e8f565b604080516001600160a01b039092168252519081900360200190f35b6104f0610e9e565b6104f0610ead565b61049a6004803603602081101561053257600080fd5b50351515610ebc565b6104e66004803603606081101561055157600080fd5b810190602081018135600160201b81111561056b57600080fd5b82018360208201111561057d57600080fd5b803590602001918460208302840111600160201b8311171561059e57600080fd5b919390929091602081019035600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460208302840111600160201b831117156105ee57600080fd5b9193509150351515610f4e565b61041c6004803603602081101561061157600080fd5b50356001600160a01b0316610fea565b61041c6004803603602081101561063757600080fd5b5035610ffc565b61041c6004803603602081101561065457600080fd5b503561109e565b61049a6111c8565b61041c6004803603604081101561067957600080fd5b506001600160a01b03813581169160200135166111d1565b61049a6111ee565b61041c600480360360208110156106af57600080fd5b50356001600160a01b03166111fd565b61041c61120f565b6104e6600480360360608110156106dd57600080fd5b506001600160a01b038135169060208101359060400135611215565b6104e66004803603602081101561070f57600080fd5b50356001600160a01b03166112fa565b61041c6004803603602081101561073557600080fd5b5035611434565b6104e66004803603604081101561075257600080fd5b810190602081018135600160201b81111561076c57600080fd5b82018360208201111561077e57600080fd5b803590602001918460208302840111600160201b8311171561079f57600080fd5b919390929091602081019035600160201b8111156107bc57600080fd5b8201836020820111156107ce57600080fd5b803590602001918460208302840111600160201b831117156107ef57600080fd5b509092509050611538565b6104e66004803603604081101561081057600080fd5b506001600160a01b038135169060200135151561168b565b6104f06004803603602081101561083e57600080fd5b5035611742565b61041c6004803603602081101561085b57600080fd5b50356001600160a01b0316611769565b61041c6004803603602081101561088157600080fd5b50356001600160a01b0316611834565b61041c600480360360208110156108a757600080fd5b50356001600160a01b0316611846565b6104e6600480360360408110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460208302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460208302840111600160201b8311171561096a57600080fd5b509092509050611911565b6104e66004803603602081101561098b57600080fd5b5035611a5b565b61041c611b0c565b61049a611b12565b6104f0611b20565b6104f0611b2f565b61041c600480360360208110156109c857600080fd5b50356001600160a01b0316611b3e565b61049a600480360360208110156109ee57600080fd5b50356001600160a01b0316611b50565b610a2460048036036020811015610a1457600080fd5b50356001600160a01b0316611b65565b6040805193151584526020840192909252151582820152519081900360600190f35b6104e660048036036020811015610a5c57600080fd5b50356001600160a01b0316611b8b565b6104f0611bf8565b61041c60048036036020811015610a8a57600080fd5b50356001600160a01b0316611c07565b61041c611c82565b6104f0611c88565b61041c60048036036020811015610ac057600080fd5b50356001600160a01b0316611c97565b61041c60048036036020811015610ae657600080fd5b50356001600160a01b0316611d61565b6104f0611e2c565b610b2460048036036020811015610b1457600080fd5b50356001600160a01b0316611e3b565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104f0611e65565b6104e660048036036020811015610b6a57600080fd5b50356001600160a01b0316611e74565b61041c60048036036020811015610b9057600080fd5b50356001600160a01b0316611f3b565b61041c611f4d565b6104f0611f53565b610bb8611f62565b604080516001600160e01b039092168252519081900360200190f35b6104f0611f75565b6104f0611f84565b61041c60048036036060811015610bfa57600080fd5b506001600160a01b03813581169160208101359091169060400135611f93565b6104f0612112565b6104f060048036036040811015610c3857600080fd5b506001600160a01b038135169060200135612121565b6104f0612156565b610b2460048036036020811015610c6c57600080fd5b50356001600160a01b0316612165565b61041c60048036036040811015610c9257600080fd5b506001600160a01b03813516906020013561218f565b61049a60048036036040811015610cbe57600080fd5b5080356001600160a01b0316906020013560ff1661238d565b61041c6123cf565b61049a60048036036040811015610cf557600080fd5b506001600160a01b03813581169160200135166123d5565b61041c60048036036020811015610d2357600080fd5b50356001600160a01b03166123f5565b6104f06124c0565b61041c6124cf565b61041c60048036036040811015610d5957600080fd5b506001600160a01b0381351690602001356124d5565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b610deb604051806060016040528060328152602001612f3860329139612582565b6015546001600160a01b03838116911614610e21576001600160a01b0382166000908152600960205260409020610e21906126a6565b6001600160a01b03838116600081815260326020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fc080966e9e93529edc1b244180c245bc60f3d86f1e690a17651a5e428746a8cd9281900390910190a3505050565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b6000610efc6040518060400160405280601881526020017f5f73657450726f746f636f6c50617573656428626f6f6c290000000000000000815250612582565b6018805483151562010000810262ff0000199092169190911790915560408051918252517fd7500633dd3ddd74daa7af62f8c8404c7fe4a81da179998db851696bed004b389181900360200190a15090565b610f6f604051806060016040528060298152602001612f9460299139612582565b838260005b82811015610fe05760005b82811015610fd757610fcf898984818110610f9657fe5b905060200201356001600160a01b0316888884818110610fb257fe5b90506020020135600881118015610fc857600080fd5b50876126f0565b600101610f7f565b50600101610f74565b5050505050505050565b60166020526000908152604090205481565b60006017548280821415611045576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61104d6127a8565b6017805490859055604080518281526020810187905281517f73747d68b346dce1e932bcd238282e7ac84c01569e1f8d0469c222fdc6e9d5a4929181900390910190a160005b9350505b5050919050565b600060055482808214156110e7576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b6110ef6127a8565b6110f7612f24565b50604080516020810190915284815261110e612f24565b506040805160208101909152670c7d713b49da0000815261112d612f24565b50604080516020810190915266b1a2bc2ec50000815261114d82846127fa565b8061115d575061115d8184612801565b156111775761116d600580612808565b9550505050611097565b600580549088905560408051828152602081018a905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a1600098975050505050505050565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b601b546001600160a01b0390811690849081168214156112665760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b61126e6127a8565b6112778561286e565b601b546001600160a01b031615611290576112906128c1565b601b80546001600160a01b0319166001600160a01b038716908117909155601c859055601d849055604080518681526020810186905281517f7059037d74ee16b0fb06a4a30f3348dd2635f301f92e373c92899a25a522ef6e929181900390910190a25050505050565b6113026127a8565b61130b8161286e565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b50516033549091506001600160a01b038083169116146113d7576040805162461bcd60e51b815260206004820152601a60248201527f696e76616c6964207876732076746f6b656e2061646472657373000000000000604482015290519081900360640190fd5b6034546040516001600160a01b038085169216907f2565e1579c0926afb7113edbfd85373e85cadaa3e0346f04de19686a2bb86ed190600090a350603480546001600160a01b0319166001600160a01b0392909216919091179055565b6000600654828082141561147d576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61149e604051806060016040528060218152602001612fbd60219139612582565b670de0b6b3a76400008410156114ee576040805162461bcd60e51b815260206004820152601060248201526f0d2dcc6cadce8d2ecca40784062ca62760831b604482015290519081900360640190fd5b6006805490859055604080518281526020810187905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611093565b611559604051806060016040528060298152602001612fde60299139612582565b8281811580159061156957508082145b6115aa576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b82811015611682578484828181106115c157fe5b90506020020135602760008989858181106115d857fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000208190555086868281811061161857fe5b905060200201356001600160a01b03166001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f886868481811061165e57fe5b905060200201356040518082815260200191505060405180910390a26001016115ad565b50505050505050565b6116ac60405180606001604052806023815260200161300760239139612582565b6015546001600160a01b038381169116146116e2576001600160a01b03821660009081526009602052604090206116e2906126a6565b6001600160a01b0382166000818152602d6020908152604091829020805460ff1916851515908117909155825190815291517f03561d5280ebb02280893b1d60978e4a27e7654a149c5d0e7c2cf65389ce16949281900390910190a25050565b600d818154811061174f57fe5b6000918252602090912001546001600160a01b0316905081565b6004546000906001600160a01b0390811690839081168214156117bd5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6117c56127a8565b6117ce8461286e565b600480546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611093565b602b6020526000908152604090205481565b600a546000906001600160a01b03908116908390811682141561189a5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6118a26127a8565b6118ab8461286e565b600a80546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e929181900390910190a16000611093565b61193260405180606001604052806029815260200161302a60299139612582565b8281811580159061194257508082145b611983576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b828110156116825784848281811061199a57fe5b90506020020135601f60008989858181106119b157fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106119f157fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611a3757fe5b905060200201356040518082815260200191505060405180910390a2600101611986565b601a548180821415611aa2576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b611aaa6127a8565b601b546001600160a01b031615611ac357611ac36128c1565b601a805490849055604080518281526020810186905281517fe81d4ac15e5afa1e708e66664eddc697177423d950d133bda8262d8885e6da3b929181900390910190a150505050565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b611b936127a8565b611b9c8161286e565b6033546040516001600160a01b038084169216907ffe7fd0d872def0f65050e9f38fc6691d0c192c694a56f09b04bec5fb2ea61f2b90600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6015546001600160a01b031681565b6000611c116127a8565b611c1a8261286e565b603180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fcb20dab7409e4fb972d9adccb39530520b226ce6940d85c9523a499b950b6ea3929181900390910190a160009392505050565b60075481565b6025546001600160a01b031681565b6026546000906001600160a01b039081169083908116821415611ceb5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611cf36127a8565b611cfc8461286e565b602680546001600160a01b038681166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0f7eb572d1b3053a0a3a33c04151364cf88d163182a5e4e1088cb8e52321e08a9281900390910190a16000611093565b6015546000906001600160a01b039081169083908116821415611db55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611dbd6127a8565b611dc68461286e565b601580546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fe1ddcb2dab8e5b03cfc8c67a0d5861d91d16f7bd2612fd381faf4541d212c9b2929181900390910190a16000611093565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b6025546001600160a01b039081169082908116821415611ec55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611ecd6127a8565b611ed68361286e565b602580546001600160a01b038581166001600160a01b0319831681179093556040805191909216808252602082019390935281517fa5ea5616d5f6dbbaa62fdfcf3856723216eed485c394d9e51ec8e6d40e1d1ac1929181900390910190a150505050565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b602054600090611fab906001600160a01b0316612a88565b670de0b6b3a76400008210611ff9576040805162461bcd60e51b815260206004820152600f60248201526e70657263656e74203e3d203130302560881b604482015290519081900360640190fd5b6120028461286e565b61200b8361286e565b6020805460218054602280546001600160a01b038a81166001600160a01b0319808816821789558b8316908616179095559188905560408051958316808752968601949094528351929091169390927f29f06ea15931797ebaed313d81d100963dc22cb213cb4ce2737b5a62b1a8b1e892918290030190a1604080516001600160a01b0380851682528816602082015281517f8de763046d7b8f08b6c3d03543de1d615309417842bb5d2d62f110f65809ddac929181900390910190a1604080518281526020810187905281517f0893f8f4101baaabbeb513f96761e7a36eb837403c82cc651c292a4abdc94ed7929181900390910190a1600093505050505b9392505050565b6026546001600160a01b031681565b6008602052816000526040600020818154811061213a57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526009602052604081206001015482808214156121ef576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61221060405180606001604052806025815260200161309560259139612582565b6122198561286e565b6001600160a01b038516600090815260096020526040902061223a816126a6565b612242612f24565b506040805160208101909152858152612259612f24565b506040805160208101909152670c7d713b49da0000815261227a81836127fa565b156122955761228b60066008612808565b9550505050612385565b861580159061231e5750600480546040805163fc57d4df60e01b81526001600160a01b038c8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d602081101561231a57600080fd5b5051155b1561232f5761228b600d6009612808565b6001830180549088905560408051828152602081018a905281516001600160a01b038c16927f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5928290030190a260009650505050505b505092915050565b6001600160a01b0382166000908152602960205260408120818360088111156123b257fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b603260209081526000928352604080842090915290825290205460ff1681565b6028546000906001600160a01b0390811690839081168214156124495760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6124516127a8565b61245a8461286e565b602880546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0f1eca7612e020f6e4582bcead0573eba4b5f7b56668754c6aed82ef12057dd4929181900390910190a16000611093565b6000546001600160a01b031681565b601a5481565b60006124df612aea565b60185460ff161580156124fa5750601854610100900460ff16155b61253b576040805162461bcd60e51b815260206004820152600d60248201526c159052481a5cc81c185d5cd959609a1b604482015290519081900360640190fd5b6015546001600160a01b0316331461256057612559600e6016612808565b90506123c9565b6001600160a01b03831660009081526016602052604081208390559392505050565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156125eb5781810151838201526020016125d3565b50505050905090810190601f1680156126185780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561263657600080fd5b505afa15801561264a573d6000803e3d6000fd5b505050506040513d602081101561266057600080fd5b50516126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b805460ff166126a3576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612711906126a6565b6001600160a01b0383166000908152602960205260408120829184600881111561273757fe5b81526020810191909152604001600020805460ff191691151591909117905581600881111561276257fe5b60408051831515815290516001600160a01b038616917f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d919081900360200190a3505050565b6000546001600160a01b031633146127f8576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b565b5190511090565b5190511190565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601381111561283757fe5b83601881111561284357fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561210b57fe5b6001600160a01b0381166126a3576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b601c5415806128d85750601c546128d6612b3d565b105b156128e2576127f8565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561293257600080fd5b505afa158015612946573d6000803e3d6000fd5b505050506040513d602081101561295c57600080fd5b505190508061296c5750506127f8565b60008061298261297a612b3d565b601c54612b41565b90506000612992601a5483612b7b565b90508084106129a3578092506129a7565b8392505b601d548310156129bb5750505050506127f8565b6129c3612b3d565b601c55601b546129e6906001600160a01b0387811691168563ffffffff612bbd16565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a6957600080fd5b505af1158015612a7d573d6000803e3d6000fd5b505050505050505050565b6000546001600160a01b0316331480612aa95750336001600160a01b038216145b6126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b60185462010000900460ff16156127f8576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b4390565b600061210b8383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250612c14565b600061210b83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250612cab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612c0f908490612d2a565b505050565b60008184841115612ca35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c68578181015183820152602001612c50565b50505050905090810190601f168015612c955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000831580612cb8575082155b15612cc55750600061210b565b83830283858281612cd257fe5b04148390612d215760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c68578181015183820152602001612c50565b50949350505050565b612d3c826001600160a01b0316612ee8565b612d8d576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612dcb5780518252601f199092019160209182019101612dac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612e2d576040519150601f19603f3d011682016040523d82523d6000602084013e612e32565b606091505b509150915081612e89576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115612ee257808060200190516020811015612ea557600080fd5b5051612ee25760405162461bcd60e51b815260040180806020018281038252602a815260200180612f6a602a913960400191505060405180910390fd5b50505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612f1c57508115155b949350505050565b604051806020016040528060008152509056fe5f736574466f726365644c69717569646174696f6e466f725573657228616464726573732c616464726573732c626f6f6c295361666542455032303a204245503230206f7065726174696f6e20646964206e6f7420737563636565645f736574416374696f6e7350617573656428616464726573735b5d2c75696e74385b5d2c626f6f6c295f7365744c69717569646174696f6e496e63656e746976652875696e74323536295f7365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d295f736574466f726365644c69717569646174696f6e28616464726573732c626f6f6c295f7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d296f6c642076616c75652069732073616d65206173206e65772076616c756500006f6c6420616464726573732069732073616d65206173206e657720616464726573735f736574436f6c6c61746572616c466163746f7228616464726573732c75696e7432353629a265627a7a7231582077590d2a11f73c0c0e36d7c0200cb6249886b0adc220f0460efe3b2556a4de9264736f6c63430005100032", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103f15760003560e01c80637dc0d1d011610215578063bf32442d11610125578063e37d4b79116100b8578063f445d70311610087578063f445d70314610cdf578063f519fc3014610d0d578063f851a44014610d33578063fa6331d814610d3b578063fd51a3ad14610d43576103f1565b8063e37d4b7914610c56578063e4028eee14610c7c578063e85a296014610ca8578063e875544614610cd7576103f1565b8063d24febad116100f4578063d24febad14610be4578063d3270f9914610c1a578063dce1544914610c22578063dcfbc0c714610c4e576103f1565b8063bf32442d14610ba8578063c5b4db5514610bb0578063c5f956af14610bd4578063c7ee005e14610bdc576103f1565b80639bb27d62116101a8578063b8324c7c11610177578063b8324c7c14610afe578063bb82aa5e14610b4c578063bb85745014610b54578063bbb8864a14610b7a578063bec04f7214610ba0576103f1565b80639bb27d6214610aa25780639bf34cbb14610aaa5780639cfdd9e614610ad0578063b2eafc3914610af6576103f1565b8063919a3736116101e4578063919a373614610a465780639254f5e514610a6c5780639460c8b514610a7457806394b2294b14610a9a576103f1565b80637dc0d1d0146109aa5780638a7dc165146109b25780638c1ac18a146109d85780638e8f294b146109fe576103f1565b8063425fad581161031057806352d84d1e116102a3578063607ef6c111610272578063607ef6c1146108b75780636662c7c914610975578063719f701b14610992578063765513831461099a5780637d172bd5146109a2576103f1565b806352d84d1e1461082857806355ee1fe1146108455780635dd3fc9d1461086b5780635f5af1aa14610891576103f1565b80634ef233fc116102df5780634ef233fc146106f95780634fd42e171461071f57806351a485e41461073c578063522c656b146107fa576103f1565b8063425fad58146106915780634a584432146106995780634ada90af146106bf5780634e0853db146106c7576103f1565b806326782247116103885780632ec04124116103575780632ec0412414610621578063317b0b771461063e5780634088c73e1461065b57806341a18d2c14610663576103f1565b806326782247146105145780632a6a60651461051c5780632b5d790c1461053b5780632bc7e29e146105fb576103f1565b806310b98338116103c457806310b983381461046c57806317db2163146104ae57806321af4569146104e857806324a3d6221461050c576103f1565b806302c3bcbb146103f657806304ef9d581461042e57806308e0225c146104365780630db4b4e514610464575b600080fd5b61041c6004803603602081101561040c57600080fd5b50356001600160a01b0316610d6f565b60408051918252519081900360200190f35b61041c610d81565b61041c6004803603604081101561044c57600080fd5b506001600160a01b0381358116916020013516610d87565b61041c610da4565b61049a6004803603604081101561048257600080fd5b506001600160a01b0381358116916020013516610daa565b604080519115158252519081900360200190f35b6104e6600480360360608110156104c457600080fd5b506001600160a01b038135811691602081013590911690604001351515610dca565b005b6104f0610e8f565b604080516001600160a01b039092168252519081900360200190f35b6104f0610e9e565b6104f0610ead565b61049a6004803603602081101561053257600080fd5b50351515610ebc565b6104e66004803603606081101561055157600080fd5b810190602081018135600160201b81111561056b57600080fd5b82018360208201111561057d57600080fd5b803590602001918460208302840111600160201b8311171561059e57600080fd5b919390929091602081019035600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460208302840111600160201b831117156105ee57600080fd5b9193509150351515610f4e565b61041c6004803603602081101561061157600080fd5b50356001600160a01b0316610fea565b61041c6004803603602081101561063757600080fd5b5035610ffc565b61041c6004803603602081101561065457600080fd5b503561109e565b61049a6111c8565b61041c6004803603604081101561067957600080fd5b506001600160a01b03813581169160200135166111d1565b61049a6111ee565b61041c600480360360208110156106af57600080fd5b50356001600160a01b03166111fd565b61041c61120f565b6104e6600480360360608110156106dd57600080fd5b506001600160a01b038135169060208101359060400135611215565b6104e66004803603602081101561070f57600080fd5b50356001600160a01b03166112fa565b61041c6004803603602081101561073557600080fd5b5035611434565b6104e66004803603604081101561075257600080fd5b810190602081018135600160201b81111561076c57600080fd5b82018360208201111561077e57600080fd5b803590602001918460208302840111600160201b8311171561079f57600080fd5b919390929091602081019035600160201b8111156107bc57600080fd5b8201836020820111156107ce57600080fd5b803590602001918460208302840111600160201b831117156107ef57600080fd5b509092509050611538565b6104e66004803603604081101561081057600080fd5b506001600160a01b038135169060200135151561168b565b6104f06004803603602081101561083e57600080fd5b5035611742565b61041c6004803603602081101561085b57600080fd5b50356001600160a01b0316611769565b61041c6004803603602081101561088157600080fd5b50356001600160a01b0316611834565b61041c600480360360208110156108a757600080fd5b50356001600160a01b0316611846565b6104e6600480360360408110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460208302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460208302840111600160201b8311171561096a57600080fd5b509092509050611911565b6104e66004803603602081101561098b57600080fd5b5035611a5b565b61041c611b0c565b61049a611b12565b6104f0611b20565b6104f0611b2f565b61041c600480360360208110156109c857600080fd5b50356001600160a01b0316611b3e565b61049a600480360360208110156109ee57600080fd5b50356001600160a01b0316611b50565b610a2460048036036020811015610a1457600080fd5b50356001600160a01b0316611b65565b6040805193151584526020840192909252151582820152519081900360600190f35b6104e660048036036020811015610a5c57600080fd5b50356001600160a01b0316611b8b565b6104f0611bf8565b61041c60048036036020811015610a8a57600080fd5b50356001600160a01b0316611c07565b61041c611c82565b6104f0611c88565b61041c60048036036020811015610ac057600080fd5b50356001600160a01b0316611c97565b61041c60048036036020811015610ae657600080fd5b50356001600160a01b0316611d61565b6104f0611e2c565b610b2460048036036020811015610b1457600080fd5b50356001600160a01b0316611e3b565b604080516001600160e01b03909316835263ffffffff90911660208301528051918290030190f35b6104f0611e65565b6104e660048036036020811015610b6a57600080fd5b50356001600160a01b0316611e74565b61041c60048036036020811015610b9057600080fd5b50356001600160a01b0316611f3b565b61041c611f4d565b6104f0611f53565b610bb8611f62565b604080516001600160e01b039092168252519081900360200190f35b6104f0611f75565b6104f0611f84565b61041c60048036036060811015610bfa57600080fd5b506001600160a01b03813581169160208101359091169060400135611f93565b6104f0612112565b6104f060048036036040811015610c3857600080fd5b506001600160a01b038135169060200135612121565b6104f0612156565b610b2460048036036020811015610c6c57600080fd5b50356001600160a01b0316612165565b61041c60048036036040811015610c9257600080fd5b506001600160a01b03813516906020013561218f565b61049a60048036036040811015610cbe57600080fd5b5080356001600160a01b0316906020013560ff1661238d565b61041c6123cf565b61049a60048036036040811015610cf557600080fd5b506001600160a01b03813581169160200135166123d5565b61041c60048036036020811015610d2357600080fd5b50356001600160a01b03166123f5565b6104f06124c0565b61041c6124cf565b61041c60048036036040811015610d5957600080fd5b506001600160a01b0381351690602001356124d5565b60276020526000908152604090205481565b60225481565b601360209081526000928352604080842090915290825290205481565b601d5481565b602c60209081526000928352604080842090915290825290205460ff1681565b610deb604051806060016040528060328152602001612f3860329139612582565b6015546001600160a01b03838116911614610e21576001600160a01b0382166000908152600960205260409020610e21906126a6565b6001600160a01b03838116600081815260326020908152604080832094871680845294825291829020805460ff1916861515908117909155825190815291517fc080966e9e93529edc1b244180c245bc60f3d86f1e690a17651a5e428746a8cd9281900390910190a3505050565b601e546001600160a01b031681565b600a546001600160a01b031681565b6001546001600160a01b031681565b6000610efc6040518060400160405280601881526020017f5f73657450726f746f636f6c50617573656428626f6f6c290000000000000000815250612582565b6018805483151562010000810262ff0000199092169190911790915560408051918252517fd7500633dd3ddd74daa7af62f8c8404c7fe4a81da179998db851696bed004b389181900360200190a15090565b610f6f604051806060016040528060298152602001612f9460299139612582565b838260005b82811015610fe05760005b82811015610fd757610fcf898984818110610f9657fe5b905060200201356001600160a01b0316888884818110610fb257fe5b90506020020135600881118015610fc857600080fd5b50876126f0565b600101610f7f565b50600101610f74565b5050505050505050565b60166020526000908152604090205481565b60006017548280821415611045576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61104d6127a8565b6017805490859055604080518281526020810187905281517f73747d68b346dce1e932bcd238282e7ac84c01569e1f8d0469c222fdc6e9d5a4929181900390910190a160005b9350505b5050919050565b600060055482808214156110e7576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b6110ef6127a8565b6110f7612f24565b50604080516020810190915284815261110e612f24565b506040805160208101909152670c7d713b49da0000815261112d612f24565b50604080516020810190915266b1a2bc2ec50000815261114d82846127fa565b8061115d575061115d8184612801565b156111775761116d600580612808565b9550505050611097565b600580549088905560408051828152602081018a905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a1600098975050505050505050565b60185460ff1681565b601260209081526000928352604080842090915290825290205481565b60185462010000900460ff1681565b601f6020526000908152604090205481565b60065481565b601b546001600160a01b0390811690849081168214156112665760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b61126e6127a8565b6112778561286e565b601b546001600160a01b031615611290576112906128c1565b601b80546001600160a01b0319166001600160a01b038716908117909155601c859055601d849055604080518681526020810186905281517f7059037d74ee16b0fb06a4a30f3348dd2635f301f92e373c92899a25a522ef6e929181900390910190a25050505050565b6113026127a8565b61130b8161286e565b6000816001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561134657600080fd5b505afa15801561135a573d6000803e3d6000fd5b505050506040513d602081101561137057600080fd5b50516033549091506001600160a01b038083169116146113d7576040805162461bcd60e51b815260206004820152601a60248201527f696e76616c6964207876732076746f6b656e2061646472657373000000000000604482015290519081900360640190fd5b6034546040516001600160a01b038085169216907f2565e1579c0926afb7113edbfd85373e85cadaa3e0346f04de19686a2bb86ed190600090a350603480546001600160a01b0319166001600160a01b0392909216919091179055565b6000600654828082141561147d576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61149e604051806060016040528060218152602001612fbd60219139612582565b670de0b6b3a76400008410156114ee576040805162461bcd60e51b815260206004820152601060248201526f0d2dcc6cadce8d2ecca40784062ca62760831b604482015290519081900360640190fd5b6006805490859055604080518281526020810187905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a16000611093565b611559604051806060016040528060298152602001612fde60299139612582565b8281811580159061156957508082145b6115aa576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b82811015611682578484828181106115c157fe5b90506020020135602760008989858181106115d857fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000208190555086868281811061161857fe5b905060200201356001600160a01b03166001600160a01b03167f9e0ad9cee10bdf36b7fbd38910c0bdff0f275ace679b45b922381c2723d676f886868481811061165e57fe5b905060200201356040518082815260200191505060405180910390a26001016115ad565b50505050505050565b6116ac60405180606001604052806023815260200161300760239139612582565b6015546001600160a01b038381169116146116e2576001600160a01b03821660009081526009602052604090206116e2906126a6565b6001600160a01b0382166000818152602d6020908152604091829020805460ff1916851515908117909155825190815291517f03561d5280ebb02280893b1d60978e4a27e7654a149c5d0e7c2cf65389ce16949281900390910190a25050565b600d818154811061174f57fe5b6000918252602090912001546001600160a01b0316905081565b6004546000906001600160a01b0390811690839081168214156117bd5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6117c56127a8565b6117ce8461286e565b600480546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e22929181900390910190a16000611093565b602b6020526000908152604090205481565b600a546000906001600160a01b03908116908390811682141561189a5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6118a26127a8565b6118ab8461286e565b600a80546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e929181900390910190a16000611093565b61193260405180606001604052806029815260200161302a60299139612582565b8281811580159061194257508082145b611983576040805162461bcd60e51b815260206004820152600d60248201526c1a5b9d985b1a59081a5b9c1d5d609a1b604482015290519081900360640190fd5b60005b828110156116825784848281811061199a57fe5b90506020020135601f60008989858181106119b157fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020819055508686828181106119f157fe5b905060200201356001600160a01b03166001600160a01b03167f6f1951b2aad10f3fc81b86d91105b413a5b3f847a34bbc5ce1904201b14438f6868684818110611a3757fe5b905060200201356040518082815260200191505060405180910390a2600101611986565b601a548180821415611aa2576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b611aaa6127a8565b601b546001600160a01b031615611ac357611ac36128c1565b601a805490849055604080518281526020810186905281517fe81d4ac15e5afa1e708e66664eddc697177423d950d133bda8262d8885e6da3b929181900390910190a150505050565b601c5481565b601854610100900460ff1681565b601b546001600160a01b031681565b6004546001600160a01b031681565b60146020526000908152604090205481565b602d6020526000908152604090205460ff1681565b60096020526000908152604090208054600182015460039092015460ff91821692911683565b611b936127a8565b611b9c8161286e565b6033546040516001600160a01b038084169216907ffe7fd0d872def0f65050e9f38fc6691d0c192c694a56f09b04bec5fb2ea61f2b90600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6015546001600160a01b031681565b6000611c116127a8565b611c1a8261286e565b603180546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517fcb20dab7409e4fb972d9adccb39530520b226ce6940d85c9523a499b950b6ea3929181900390910190a160009392505050565b60075481565b6025546001600160a01b031681565b6026546000906001600160a01b039081169083908116821415611ceb5760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611cf36127a8565b611cfc8461286e565b602680546001600160a01b038681166001600160a01b0319831617928390556040805192821680845293909116602083015280517f0f7eb572d1b3053a0a3a33c04151364cf88d163182a5e4e1088cb8e52321e08a9281900390910190a16000611093565b6015546000906001600160a01b039081169083908116821415611db55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611dbd6127a8565b611dc68461286e565b601580546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517fe1ddcb2dab8e5b03cfc8c67a0d5861d91d16f7bd2612fd381faf4541d212c9b2929181900390910190a16000611093565b6020546001600160a01b031681565b6010602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6002546001600160a01b031681565b6025546001600160a01b039081169082908116821415611ec55760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b611ecd6127a8565b611ed68361286e565b602580546001600160a01b038581166001600160a01b0319831681179093556040805191909216808252602082019390935281517fa5ea5616d5f6dbbaa62fdfcf3856723216eed485c394d9e51ec8e6d40e1d1ac1929181900390910190a150505050565b602a6020526000908152604090205481565b60175481565b6033546001600160a01b031690565b6ec097ce7bc90715b34b9f100000000081565b6021546001600160a01b031681565b6031546001600160a01b031681565b602054600090611fab906001600160a01b0316612a88565b670de0b6b3a76400008210611ff9576040805162461bcd60e51b815260206004820152600f60248201526e70657263656e74203e3d203130302560881b604482015290519081900360640190fd5b6120028461286e565b61200b8361286e565b6020805460218054602280546001600160a01b038a81166001600160a01b0319808816821789558b8316908616179095559188905560408051958316808752968601949094528351929091169390927f29f06ea15931797ebaed313d81d100963dc22cb213cb4ce2737b5a62b1a8b1e892918290030190a1604080516001600160a01b0380851682528816602082015281517f8de763046d7b8f08b6c3d03543de1d615309417842bb5d2d62f110f65809ddac929181900390910190a1604080518281526020810187905281517f0893f8f4101baaabbeb513f96761e7a36eb837403c82cc651c292a4abdc94ed7929181900390910190a1600093505050505b9392505050565b6026546001600160a01b031681565b6008602052816000526040600020818154811061213a57fe5b6000918252602090912001546001600160a01b03169150829050565b6003546001600160a01b031681565b6011602052600090815260409020546001600160e01b03811690600160e01b900463ffffffff1682565b6001600160a01b03821660009081526009602052604081206001015482808214156121ef576040805162461bcd60e51b815260206004820152601e6024820152600080516020613053833981519152604482015290519081900360640190fd5b61221060405180606001604052806025815260200161309560259139612582565b6122198561286e565b6001600160a01b038516600090815260096020526040902061223a816126a6565b612242612f24565b506040805160208101909152858152612259612f24565b506040805160208101909152670c7d713b49da0000815261227a81836127fa565b156122955761228b60066008612808565b9550505050612385565b861580159061231e5750600480546040805163fc57d4df60e01b81526001600160a01b038c8116948201949094529051929091169163fc57d4df91602480820192602092909190829003018186803b1580156122f057600080fd5b505afa158015612304573d6000803e3d6000fd5b505050506040513d602081101561231a57600080fd5b5051155b1561232f5761228b600d6009612808565b6001830180549088905560408051828152602081018a905281516001600160a01b038c16927f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc5928290030190a260009650505050505b505092915050565b6001600160a01b0382166000908152602960205260408120818360088111156123b257fe5b815260208101919091526040016000205460ff1690505b92915050565b60055481565b603260209081526000928352604080842090915290825290205460ff1681565b6028546000906001600160a01b0390811690839081168214156124495760405162461bcd60e51b81526004018080602001828103825260228152602001806130736022913960400191505060405180910390fd5b6124516127a8565b61245a8461286e565b602880546001600160a01b038681166001600160a01b0319831681179093556040805191909216808252602082019390935281517f0f1eca7612e020f6e4582bcead0573eba4b5f7b56668754c6aed82ef12057dd4929181900390910190a16000611093565b6000546001600160a01b031681565b601a5481565b60006124df612aea565b60185460ff161580156124fa5750601854610100900460ff16155b61253b576040805162461bcd60e51b815260206004820152600d60248201526c159052481a5cc81c185d5cd959609a1b604482015290519081900360640190fd5b6015546001600160a01b0316331461256057612559600e6016612808565b90506123c9565b6001600160a01b03831660009081526016602052604081208390559392505050565b602854604080516318c5e8ab60e01b81523360048201818152602483019384528551604484015285516001600160a01b03909516946318c5e8ab949293879391606490910190602085019080838360005b838110156125eb5781810151838201526020016125d3565b50505050905090810190601f1680156126185780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561263657600080fd5b505afa15801561264a573d6000803e3d6000fd5b505050506040513d602081101561266057600080fd5b50516126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b50565b805460ff166126a3576040805162461bcd60e51b81526020600482015260116024820152701b585c9ad95d081b9bdd081b1a5cdd1959607a1b604482015290519081900360640190fd5b6001600160a01b0383166000908152600960205260409020612711906126a6565b6001600160a01b0383166000908152602960205260408120829184600881111561273757fe5b81526020810191909152604001600020805460ff191691151591909117905581600881111561276257fe5b60408051831515815290516001600160a01b038616917f35007a986bcd36d2f73fc7f1b73762e12eadb4406dd163194950fd3b5a6a827d919081900360200190a3505050565b6000546001600160a01b031633146127f8576040805162461bcd60e51b815260206004820152600e60248201526d37b7363c9030b236b4b71031b0b760911b604482015290519081900360640190fd5b565b5190511090565b5190511190565b60007f45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa083601381111561283757fe5b83601881111561284357fe5b604080519283526020830191909152600082820152519081900360600190a182601381111561210b57fe5b6001600160a01b0381166126a3576040805162461bcd60e51b815260206004820152601560248201527463616e2774206265207a65726f206164647265737360581b604482015290519081900360640190fd5b601c5415806128d85750601c546128d6612b3d565b105b156128e2576127f8565b603354604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b15801561293257600080fd5b505afa158015612946573d6000803e3d6000fd5b505050506040513d602081101561295c57600080fd5b505190508061296c5750506127f8565b60008061298261297a612b3d565b601c54612b41565b90506000612992601a5483612b7b565b90508084106129a3578092506129a7565b8392505b601d548310156129bb5750505050506127f8565b6129c3612b3d565b601c55601b546129e6906001600160a01b0387811691168563ffffffff612bbd16565b6040805184815290517ff6d4b8f74d85a6e2d7a50225957b8a6cfec69ad92f5905627260541aa0a5565d9181900360200190a1601b60009054906101000a90046001600160a01b03166001600160a01b031663faa1809e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a6957600080fd5b505af1158015612a7d573d6000803e3d6000fd5b505050505050505050565b6000546001600160a01b0316331480612aa95750336001600160a01b038216145b6126a3576040805162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b60185462010000900460ff16156127f8576040805162461bcd60e51b81526020600482015260126024820152711c1c9bdd1bd8dbdb081a5cc81c185d5cd95960721b604482015290519081900360640190fd5b4390565b600061210b8383604051806040016040528060158152602001747375627472616374696f6e20756e646572666c6f7760581b815250612c14565b600061210b83836040518060400160405280601781526020017f6d756c7469706c69636174696f6e206f766572666c6f77000000000000000000815250612cab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612c0f908490612d2a565b505050565b60008184841115612ca35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612c68578181015183820152602001612c50565b50505050905090810190601f168015612c955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000831580612cb8575082155b15612cc55750600061210b565b83830283858281612cd257fe5b04148390612d215760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612c68578181015183820152602001612c50565b50949350505050565b612d3c826001600160a01b0316612ee8565b612d8d576040805162461bcd60e51b815260206004820152601f60248201527f5361666542455032303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612dcb5780518252601f199092019160209182019101612dac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612e2d576040519150601f19603f3d011682016040523d82523d6000602084013e612e32565b606091505b509150915081612e89576040805162461bcd60e51b815260206004820181905260248201527f5361666542455032303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115612ee257808060200190516020811015612ea557600080fd5b5051612ee25760405162461bcd60e51b815260040180806020018281038252602a815260200180612f6a602a913960400191505060405180910390fd5b50505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612f1c57508115155b949350505050565b604051806020016040528060008152509056fe5f736574466f726365644c69717569646174696f6e466f725573657228616464726573732c616464726573732c626f6f6c295361666542455032303a204245503230206f7065726174696f6e20646964206e6f7420737563636565645f736574416374696f6e7350617573656428616464726573735b5d2c75696e74385b5d2c626f6f6c295f7365744c69717569646174696f6e496e63656e746976652875696e74323536295f7365744d61726b6574537570706c794361707328616464726573735b5d2c75696e743235365b5d295f736574466f726365644c69717569646174696f6e28616464726573732c626f6f6c295f7365744d61726b6574426f72726f774361707328616464726573735b5d2c75696e743235365b5d296f6c642076616c75652069732073616d65206173206e65772076616c756500006f6c6420616464726573732069732073616d65206173206e657720616464726573735f736574436f6c6c61746572616c466163746f7228616464726573732c75696e7432353629a265627a7a7231582077590d2a11f73c0c0e36d7c0200cb6249886b0adc220f0460efe3b2556a4de9264736f6c63430005100032", "devdoc": { "author": "Venus", "details": "This facet contains all the setters for the states", @@ -1924,9 +1924,9 @@ } }, "_setMarketBorrowCaps(address[],uint256[])": { - "details": "Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to unlimited borrowing", + "details": "Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed", "params": { - "newBorrowCaps": "The new borrow cap values in underlying to be set. A value of 0 corresponds to unlimited borrowing", + "newBorrowCaps": "The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed", "vTokens": "The addresses of the markets (tokens) to change the borrow caps for" } }, @@ -2097,7 +2097,7 @@ "storageLayout": { "storage": [ { - "astId": 2391, + "astId": 2510, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "admin", "offset": 0, @@ -2105,7 +2105,7 @@ "type": "t_address" }, { - "astId": 2393, + "astId": 2512, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "pendingAdmin", "offset": 0, @@ -2113,7 +2113,7 @@ "type": "t_address" }, { - "astId": 2395, + "astId": 2514, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "comptrollerImplementation", "offset": 0, @@ -2121,7 +2121,7 @@ "type": "t_address" }, { - "astId": 2397, + "astId": 2516, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "pendingComptrollerImplementation", "offset": 0, @@ -2129,15 +2129,15 @@ "type": "t_address" }, { - "astId": 2404, + "astId": 2523, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "oracle", "offset": 0, "slot": "4", - "type": "t_contract(PriceOracle)12051" + "type": "t_contract(PriceOracle)12353" }, { - "astId": 2406, + "astId": 2525, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "closeFactorMantissa", "offset": 0, @@ -2145,7 +2145,7 @@ "type": "t_uint256" }, { - "astId": 2408, + "astId": 2527, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "liquidationIncentiveMantissa", "offset": 0, @@ -2153,7 +2153,7 @@ "type": "t_uint256" }, { - "astId": 2410, + "astId": 2529, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "maxAssets", "offset": 0, @@ -2161,23 +2161,23 @@ "type": "t_uint256" }, { - "astId": 2415, + "astId": 2534, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "accountAssets", "offset": 0, "slot": "8", - "type": "t_mapping(t_address,t_array(t_contract(VToken)22978)dyn_storage)" + "type": "t_mapping(t_address,t_array(t_contract(VToken)23491)dyn_storage)" }, { - "astId": 2430, + "astId": 2549, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "markets", "offset": 0, "slot": "9", - "type": "t_mapping(t_address,t_struct(Market)2426_storage)" + "type": "t_mapping(t_address,t_struct(Market)2545_storage)" }, { - "astId": 2432, + "astId": 2551, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "pauseGuardian", "offset": 0, @@ -2185,7 +2185,7 @@ "type": "t_address" }, { - "astId": 2434, + "astId": 2553, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_mintGuardianPaused", "offset": 20, @@ -2193,7 +2193,7 @@ "type": "t_bool" }, { - "astId": 2436, + "astId": 2555, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_borrowGuardianPaused", "offset": 21, @@ -2201,7 +2201,7 @@ "type": "t_bool" }, { - "astId": 2438, + "astId": 2557, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "transferGuardianPaused", "offset": 22, @@ -2209,7 +2209,7 @@ "type": "t_bool" }, { - "astId": 2440, + "astId": 2559, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "seizeGuardianPaused", "offset": 23, @@ -2217,7 +2217,7 @@ "type": "t_bool" }, { - "astId": 2444, + "astId": 2563, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "mintGuardianPaused", "offset": 0, @@ -2225,7 +2225,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2448, + "astId": 2567, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "borrowGuardianPaused", "offset": 0, @@ -2233,15 +2233,15 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2456, + "astId": 2575, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "allMarkets", "offset": 0, "slot": "13", - "type": "t_array(t_contract(VToken)22978)dyn_storage" + "type": "t_array(t_contract(VToken)23491)dyn_storage" }, { - "astId": 2458, + "astId": 2577, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusRate", "offset": 0, @@ -2249,7 +2249,7 @@ "type": "t_uint256" }, { - "astId": 2462, + "astId": 2581, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusSpeeds", "offset": 0, @@ -2257,23 +2257,23 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2466, + "astId": 2585, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusSupplyState", "offset": 0, "slot": "16", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)" }, { - "astId": 2470, + "astId": 2589, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusBorrowState", "offset": 0, "slot": "17", - "type": "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)" + "type": "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)" }, { - "astId": 2476, + "astId": 2595, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusSupplierIndex", "offset": 0, @@ -2281,7 +2281,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2482, + "astId": 2601, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusBorrowerIndex", "offset": 0, @@ -2289,7 +2289,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 2486, + "astId": 2605, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusAccrued", "offset": 0, @@ -2297,15 +2297,15 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2488, + "astId": 2607, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "vaiController", "offset": 0, "slot": "21", - "type": "t_contract(VAIControllerInterface)15527" + "type": "t_contract(VAIControllerInterface)15651" }, { - "astId": 2492, + "astId": 2611, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "mintedVAIs", "offset": 0, @@ -2313,7 +2313,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2494, + "astId": 2613, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "vaiMintRate", "offset": 0, @@ -2321,7 +2321,7 @@ "type": "t_uint256" }, { - "astId": 2496, + "astId": 2615, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "mintVAIGuardianPaused", "offset": 0, @@ -2329,7 +2329,7 @@ "type": "t_bool" }, { - "astId": 2498, + "astId": 2617, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "repayVAIGuardianPaused", "offset": 1, @@ -2337,7 +2337,7 @@ "type": "t_bool" }, { - "astId": 2500, + "astId": 2619, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "protocolPaused", "offset": 2, @@ -2345,7 +2345,7 @@ "type": "t_bool" }, { - "astId": 2502, + "astId": 2621, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusVAIRate", "offset": 0, @@ -2353,7 +2353,7 @@ "type": "t_uint256" }, { - "astId": 2507, + "astId": 2626, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusVAIVaultRate", "offset": 0, @@ -2361,7 +2361,7 @@ "type": "t_uint256" }, { - "astId": 2509, + "astId": 2628, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "vaiVaultAddress", "offset": 0, @@ -2369,7 +2369,7 @@ "type": "t_address" }, { - "astId": 2511, + "astId": 2630, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "releaseStartBlock", "offset": 0, @@ -2377,7 +2377,7 @@ "type": "t_uint256" }, { - "astId": 2513, + "astId": 2632, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "minReleaseAmount", "offset": 0, @@ -2385,7 +2385,7 @@ "type": "t_uint256" }, { - "astId": 2518, + "astId": 2637, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "borrowCapGuardian", "offset": 0, @@ -2393,7 +2393,7 @@ "type": "t_address" }, { - "astId": 2522, + "astId": 2641, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "borrowCaps", "offset": 0, @@ -2401,7 +2401,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2527, + "astId": 2646, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "treasuryGuardian", "offset": 0, @@ -2409,7 +2409,7 @@ "type": "t_address" }, { - "astId": 2529, + "astId": 2648, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "treasuryAddress", "offset": 0, @@ -2417,7 +2417,7 @@ "type": "t_address" }, { - "astId": 2531, + "astId": 2650, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "treasuryPercent", "offset": 0, @@ -2425,7 +2425,7 @@ "type": "t_uint256" }, { - "astId": 2538, + "astId": 2657, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusContributorSpeeds", "offset": 0, @@ -2433,7 +2433,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2542, + "astId": 2661, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "lastContributorBlock", "offset": 0, @@ -2441,7 +2441,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2547, + "astId": 2666, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "liquidatorContract", "offset": 0, @@ -2449,15 +2449,15 @@ "type": "t_address" }, { - "astId": 2552, + "astId": 2671, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "comptrollerLens", "offset": 0, "slot": "38", - "type": "t_contract(ComptrollerLensInterface)2366" + "type": "t_contract(ComptrollerLensInterface)2485" }, { - "astId": 2559, + "astId": 2678, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "supplyCaps", "offset": 0, @@ -2465,7 +2465,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2564, + "astId": 2683, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "accessControl", "offset": 0, @@ -2473,7 +2473,7 @@ "type": "t_address" }, { - "astId": 2570, + "astId": 2689, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_actionPaused", "offset": 0, @@ -2481,7 +2481,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_bool))" }, { - "astId": 2577, + "astId": 2696, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusBorrowSpeeds", "offset": 0, @@ -2489,7 +2489,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2581, + "astId": 2700, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "venusSupplySpeeds", "offset": 0, @@ -2497,7 +2497,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 2590, + "astId": 2709, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "approvedDelegates", "offset": 0, @@ -2505,7 +2505,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2597, + "astId": 2716, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "isForcedLiquidationEnabled", "offset": 0, @@ -2513,23 +2513,23 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2615, + "astId": 2734, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_selectorToFacetAndPosition", "offset": 0, "slot": "46", - "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2605_storage)" + "type": "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2724_storage)" }, { - "astId": 2619, + "astId": 2738, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_facetFunctionSelectors", "offset": 0, "slot": "47", - "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2611_storage)" + "type": "t_mapping(t_address,t_struct(FacetFunctionSelectors)2730_storage)" }, { - "astId": 2622, + "astId": 2741, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "_facetAddresses", "offset": 0, @@ -2537,15 +2537,15 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 2627, + "astId": 2746, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "prime", "offset": 0, "slot": "49", - "type": "t_contract(IPrime)12228" + "type": "t_contract(IPrime)12530" }, { - "astId": 2636, + "astId": 2755, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "isForcedLiquidationEnabledForUser", "offset": 0, @@ -2553,7 +2553,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" }, { - "astId": 2641, + "astId": 2760, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "xvs", "offset": 0, @@ -2561,7 +2561,7 @@ "type": "t_address" }, { - "astId": 2643, + "astId": 2762, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "xvsVToken", "offset": 0, @@ -2587,8 +2587,8 @@ "label": "bytes4[]", "numberOfBytes": "32" }, - "t_array(t_contract(VToken)22978)dyn_storage": { - "base": "t_contract(VToken)22978", + "t_array(t_contract(VToken)23491)dyn_storage": { + "base": "t_contract(VToken)23491", "encoding": "dynamic_array", "label": "contract VToken[]", "numberOfBytes": "32" @@ -2603,37 +2603,37 @@ "label": "bytes4", "numberOfBytes": "4" }, - "t_contract(ComptrollerLensInterface)2366": { + "t_contract(ComptrollerLensInterface)2485": { "encoding": "inplace", "label": "contract ComptrollerLensInterface", "numberOfBytes": "20" }, - "t_contract(IPrime)12228": { + "t_contract(IPrime)12530": { "encoding": "inplace", "label": "contract IPrime", "numberOfBytes": "20" }, - "t_contract(PriceOracle)12051": { + "t_contract(PriceOracle)12353": { "encoding": "inplace", "label": "contract PriceOracle", "numberOfBytes": "20" }, - "t_contract(VAIControllerInterface)15527": { + "t_contract(VAIControllerInterface)15651": { "encoding": "inplace", "label": "contract VAIControllerInterface", "numberOfBytes": "20" }, - "t_contract(VToken)22978": { + "t_contract(VToken)23491": { "encoding": "inplace", "label": "contract VToken", "numberOfBytes": "20" }, - "t_mapping(t_address,t_array(t_contract(VToken)22978)dyn_storage)": { + "t_mapping(t_address,t_array(t_contract(VToken)23491)dyn_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => contract VToken[])", "numberOfBytes": "32", - "value": "t_array(t_contract(VToken)22978)dyn_storage" + "value": "t_array(t_contract(VToken)23491)dyn_storage" }, "t_mapping(t_address,t_bool)": { "encoding": "mapping", @@ -2663,26 +2663,26 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_bool)" }, - "t_mapping(t_address,t_struct(FacetFunctionSelectors)2611_storage)": { + "t_mapping(t_address,t_struct(FacetFunctionSelectors)2730_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV13Storage.FacetFunctionSelectors)", "numberOfBytes": "32", - "value": "t_struct(FacetFunctionSelectors)2611_storage" + "value": "t_struct(FacetFunctionSelectors)2730_storage" }, - "t_mapping(t_address,t_struct(Market)2426_storage)": { + "t_mapping(t_address,t_struct(Market)2545_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.Market)", "numberOfBytes": "32", - "value": "t_struct(Market)2426_storage" + "value": "t_struct(Market)2545_storage" }, - "t_mapping(t_address,t_struct(VenusMarketState)2453_storage)": { + "t_mapping(t_address,t_struct(VenusMarketState)2572_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct ComptrollerV1Storage.VenusMarketState)", "numberOfBytes": "32", - "value": "t_struct(VenusMarketState)2453_storage" + "value": "t_struct(VenusMarketState)2572_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -2691,12 +2691,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2605_storage)": { + "t_mapping(t_bytes4,t_struct(FacetAddressAndPosition)2724_storage)": { "encoding": "mapping", "key": "t_bytes4", "label": "mapping(bytes4 => struct ComptrollerV13Storage.FacetAddressAndPosition)", "numberOfBytes": "32", - "value": "t_struct(FacetAddressAndPosition)2605_storage" + "value": "t_struct(FacetAddressAndPosition)2724_storage" }, "t_mapping(t_uint256,t_bool)": { "encoding": "mapping", @@ -2705,12 +2705,12 @@ "numberOfBytes": "32", "value": "t_bool" }, - "t_struct(FacetAddressAndPosition)2605_storage": { + "t_struct(FacetAddressAndPosition)2724_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetAddressAndPosition", "members": [ { - "astId": 2602, + "astId": 2721, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "facetAddress", "offset": 0, @@ -2718,7 +2718,7 @@ "type": "t_address" }, { - "astId": 2604, + "astId": 2723, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "functionSelectorPosition", "offset": 20, @@ -2728,12 +2728,12 @@ ], "numberOfBytes": "32" }, - "t_struct(FacetFunctionSelectors)2611_storage": { + "t_struct(FacetFunctionSelectors)2730_storage": { "encoding": "inplace", "label": "struct ComptrollerV13Storage.FacetFunctionSelectors", "members": [ { - "astId": 2608, + "astId": 2727, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "functionSelectors", "offset": 0, @@ -2741,7 +2741,7 @@ "type": "t_array(t_bytes4)dyn_storage" }, { - "astId": 2610, + "astId": 2729, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "facetAddressPosition", "offset": 0, @@ -2751,12 +2751,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Market)2426_storage": { + "t_struct(Market)2545_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.Market", "members": [ { - "astId": 2417, + "astId": 2536, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "isListed", "offset": 0, @@ -2764,7 +2764,7 @@ "type": "t_bool" }, { - "astId": 2419, + "astId": 2538, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "collateralFactorMantissa", "offset": 0, @@ -2772,7 +2772,7 @@ "type": "t_uint256" }, { - "astId": 2423, + "astId": 2542, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "accountMembership", "offset": 0, @@ -2780,7 +2780,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 2425, + "astId": 2544, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "isVenus", "offset": 0, @@ -2790,12 +2790,12 @@ ], "numberOfBytes": "128" }, - "t_struct(VenusMarketState)2453_storage": { + "t_struct(VenusMarketState)2572_storage": { "encoding": "inplace", "label": "struct ComptrollerV1Storage.VenusMarketState", "members": [ { - "astId": 2450, + "astId": 2569, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "index", "offset": 0, @@ -2803,7 +2803,7 @@ "type": "t_uint224" }, { - "astId": 2452, + "astId": 2571, "contract": "contracts/Comptroller/Diamond/facets/SetterFacet.sol:SetterFacet", "label": "block", "offset": 28, diff --git a/deployments/bsctestnet/solcInputs/7674fc0eb5134fe9ab2419cd8945df4b.json b/deployments/bsctestnet/solcInputs/7674fc0eb5134fe9ab2419cd8945df4b.json new file mode 100644 index 000000000..58681db5a --- /dev/null +++ b/deployments/bsctestnet/solcInputs/7674fc0eb5134fe9ab2419cd8945df4b.json @@ -0,0 +1,348 @@ +{ + "language": "Solidity", + "sources": { + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV5.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.5.16;\n\nimport \"./IAccessControlManagerV5.sol\";\n\n/**\n * @title AccessControlledV5\n * @author Venus\n * @notice This contract is helper between access control manager and actual contract. This contract further inherited by other contract (using solidity 0.5.16)\n * to integrate access controlled mechanism. It provides initialise methods and verifying access methods.\n */\ncontract AccessControlledV5 {\n /// @notice Access control manager contract\n IAccessControlManagerV5 private _accessControlManager;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n\n /// @notice Emitted when access control manager contract address is changed\n event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager);\n\n /**\n * @notice Returns the address of the access control manager contract\n */\n function accessControlManager() external view returns (IAccessControlManagerV5) {\n return _accessControlManager;\n }\n\n /**\n * @dev Internal function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n */\n function _setAccessControlManager(address accessControlManager_) internal {\n require(address(accessControlManager_) != address(0), \"invalid acess control manager address\");\n address oldAccessControlManager = address(_accessControlManager);\n _accessControlManager = IAccessControlManagerV5(accessControlManager_);\n emit NewAccessControlManager(oldAccessControlManager, accessControlManager_);\n }\n\n /**\n * @notice Reverts if the call is not allowed by AccessControlManager\n * @param signature Method signature\n */\n function _checkAccessAllowed(string memory signature) internal view {\n bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature);\n\n if (!isAllowedToCall) {\n revert(\"Unauthorized\");\n }\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/GovernorBravoDelegate.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"./GovernorBravoInterfaces.sol\";\n\n/**\n * @title GovernorBravoDelegate\n * @notice Venus Governance latest on chain governance includes several new features including variable proposal routes and fine grained pause control.\n * Variable routes for proposals allows for governance paramaters such as voting threshold and timelocks to be customized based on the risk level and\n * impact of the proposal. Added granularity to the pause control mechanism allows governance to pause individual actions on specific markets,\n * which reduces impact on the protocol as a whole. This is particularly useful when applied to isolated pools.\n *\n * The goal of **Governance** is to increase governance efficiency, while mitigating and eliminating malicious or erroneous proposals.\n *\n * ## Details\n *\n * Governance has **3 main contracts**: **GovernanceBravoDelegate, XVSVault, XVS** token.\n *\n * - XVS token is the protocol token used for protocol users to cast their vote on submitted proposals.\n * - XVSVault is the main staking contract for XVS. Users first stake their XVS in the vault and receive voting power proportional to their staked\n * tokens that they can use to vote on proposals. Users also can choose to delegate their voting power to other users.\n *\n * # Governor Bravo\n *\n * `GovernanceBravoDelegate` is main Venus Governance contract. Users interact with it to:\n * - Submit new proposal\n * - Vote on a proposal\n * - Cancel a proposal\n * - Queue a proposal for execution with a timelock executor contract.\n * `GovernanceBravoDelegate` uses the XVSVault to get restrict certain actions based on a user's voting power. The governance rules it inforces are:\n * - A user's voting power must be greater than the `proposalThreshold` to submit a proposal\n * - If a user's voting power drops below certain amount, anyone can cancel the the proposal. The governance guardian and proposal creator can also\n * cancel a proposal at anytime before it is queued for execution.\n *\n * ## Venus Improvement Proposal\n *\n * Venus Governance allows for Venus Improvement Proposals (VIPs) to be categorized based on their impact and risk levels. This allows for optimizing proposals\n * execution to allow for things such as expediting interest rate changes and quickly updating risk parameters, while moving slower on other types of proposals\n * that can prevent a larger risk to the protocol and are not urgent. There are three different types of VIPs with different proposal paramters:\n *\n * - `NORMAL`\n * - `FASTTRACK`\n * - `CRITICAL`\n *\n * When initializing the `GovernorBravo` contract, the parameters for the three routes are set. The parameters are:\n *\n * - `votingDelay`: The delay in blocks between submitting a proposal and when voting begins\n * - `votingPeriod`: The number of blocks where voting will be open\n * - `proposalThreshold`: The number of votes required in order submit a proposal\n *\n * There is also a separate timelock executor contract for each route, which is used to dispatch the VIP for execution, giving even more control over the\n * flow of each type of VIP.\n *\n * ## Voting\n *\n * After a VIP is proposed, voting is opened after the `votingDelay` has passed. For example, if `votingDelay = 0`, then voting will begin in the next block\n * after the proposal has been submitted. After the delay, the proposal state is `ACTIVE` and users can cast their vote `for`, `against`, or `abstain`,\n * weighted by their total voting power (tokens + delegated voting power). Abstaining from a voting allows for a vote to be cast and optionally include a\n * comment, without the incrementing for or against vote count. The total voting power for the user is obtained by calling XVSVault's `getPriorVotes`.\n *\n * `GovernorBravoDelegate` also accepts [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signatures for voting on proposals via the external function\n * `castVoteBySig`.\n *\n * ## Delegating\n *\n * A users voting power includes the amount of staked XVS the have staked as well as the votes delegate to them. Delegating is the process of a user loaning\n * their voting power to another, so that the latter has the combined voting power of both users. This is an important feature because it allows for a user\n * to let another user who they trust propose or vote in their place.\n *\n * The delegation of votes happens through the `XVSVault` contract by calling the `delegate` or `delegateBySig` functions. These same functions can revert\n * vote delegation by calling the same function with a value of `0`.\n */\ncontract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoEvents {\n /// @notice The name of this contract\n string public constant name = \"Venus Governor Bravo\";\n\n /// @notice The minimum setable proposal threshold\n uint public constant MIN_PROPOSAL_THRESHOLD = 150000e18; // 150,000 Xvs\n\n /// @notice The maximum setable proposal threshold\n uint public constant MAX_PROPOSAL_THRESHOLD = 300000e18; //300,000 Xvs\n\n /// @notice The minimum setable voting period\n uint public constant MIN_VOTING_PERIOD = 20 * 60 * 3; // About 3 hours, 3 secs per block\n\n /// @notice The max setable voting period\n uint public constant MAX_VOTING_PERIOD = 20 * 60 * 24 * 14; // About 2 weeks, 3 secs per block\n\n /// @notice The min setable voting delay\n uint public constant MIN_VOTING_DELAY = 1;\n\n /// @notice The max setable voting delay\n uint public constant MAX_VOTING_DELAY = 20 * 60 * 24 * 7; // About 1 week, 3 secs per block\n\n /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed\n uint public constant quorumVotes = 600000e18; // 600,000 = 2% of Xvs\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the ballot struct used by the contract\n bytes32 public constant BALLOT_TYPEHASH = keccak256(\"Ballot(uint256 proposalId,uint8 support)\");\n\n /**\n * @notice Used to initialize the contract during delegator contructor\n * @param xvsVault_ The address of the XvsVault\n * @param proposalConfigs_ Governance configs for each governance route\n * @param timelocks Timelock addresses for each governance route\n */\n function initialize(\n address xvsVault_,\n ProposalConfig[] memory proposalConfigs_,\n TimelockInterface[] memory timelocks,\n address guardian_\n ) public {\n require(address(proposalTimelocks[0]) == address(0), \"GovernorBravo::initialize: cannot initialize twice\");\n require(msg.sender == admin, \"GovernorBravo::initialize: admin only\");\n require(xvsVault_ != address(0), \"GovernorBravo::initialize: invalid xvs address\");\n require(guardian_ != address(0), \"GovernorBravo::initialize: invalid guardian\");\n require(\n timelocks.length == uint8(ProposalType.CRITICAL) + 1,\n \"GovernorBravo::initialize:number of timelocks should match number of governance routes\"\n );\n require(\n proposalConfigs_.length == uint8(ProposalType.CRITICAL) + 1,\n \"GovernorBravo::initialize:number of proposal configs should match number of governance routes\"\n );\n\n xvsVault = XvsVaultInterface(xvsVault_);\n proposalMaxOperations = 10;\n guardian = guardian_;\n\n //Set parameters for each Governance Route\n uint256 arrLength = proposalConfigs_.length;\n for (uint256 i; i < arrLength; ++i) {\n require(\n proposalConfigs_[i].votingPeriod >= MIN_VOTING_PERIOD,\n \"GovernorBravo::initialize: invalid min voting period\"\n );\n require(\n proposalConfigs_[i].votingPeriod <= MAX_VOTING_PERIOD,\n \"GovernorBravo::initialize: invalid max voting period\"\n );\n require(\n proposalConfigs_[i].votingDelay >= MIN_VOTING_DELAY,\n \"GovernorBravo::initialize: invalid min voting delay\"\n );\n require(\n proposalConfigs_[i].votingDelay <= MAX_VOTING_DELAY,\n \"GovernorBravo::initialize: invalid max voting delay\"\n );\n require(\n proposalConfigs_[i].proposalThreshold >= MIN_PROPOSAL_THRESHOLD,\n \"GovernorBravo::initialize: invalid min proposal threshold\"\n );\n require(\n proposalConfigs_[i].proposalThreshold <= MAX_PROPOSAL_THRESHOLD,\n \"GovernorBravo::initialize: invalid max proposal threshold\"\n );\n require(address(timelocks[i]) != address(0), \"GovernorBravo::initialize:invalid timelock address\");\n\n proposalConfigs[i] = proposalConfigs_[i];\n proposalTimelocks[i] = timelocks[i];\n }\n }\n\n /**\n * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold.\n * targets, values, signatures, and calldatas must be of equal length\n * @dev NOTE: Proposals with duplicate set of actions can not be queued for execution. If the proposals consists\n * of duplicate actions, it's recommended to split those actions into separate proposals\n * @param targets Target addresses for proposal calls\n * @param values BNB values for proposal calls\n * @param signatures Function signatures for proposal calls\n * @param calldatas Calldatas for proposal calls\n * @param description String description of the proposal\n * @param proposalType the type of the proposal (e.g NORMAL, FASTTRACK, CRITICAL)\n * @return Proposal id of new proposal\n */\n function propose(\n address[] memory targets,\n uint[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n string memory description,\n ProposalType proposalType\n ) public returns (uint) {\n // Reject proposals before initiating as Governor\n require(initialProposalId != 0, \"GovernorBravo::propose: Governor Bravo not active\");\n require(\n xvsVault.getPriorVotes(msg.sender, sub256(block.number, 1)) >=\n proposalConfigs[uint8(proposalType)].proposalThreshold,\n \"GovernorBravo::propose: proposer votes below proposal threshold\"\n );\n require(\n targets.length == values.length &&\n targets.length == signatures.length &&\n targets.length == calldatas.length,\n \"GovernorBravo::propose: proposal function information arity mismatch\"\n );\n require(targets.length != 0, \"GovernorBravo::propose: must provide actions\");\n require(targets.length <= proposalMaxOperations, \"GovernorBravo::propose: too many actions\");\n\n uint latestProposalId = latestProposalIds[msg.sender];\n if (latestProposalId != 0) {\n ProposalState proposersLatestProposalState = state(latestProposalId);\n require(\n proposersLatestProposalState != ProposalState.Active,\n \"GovernorBravo::propose: one live proposal per proposer, found an already active proposal\"\n );\n require(\n proposersLatestProposalState != ProposalState.Pending,\n \"GovernorBravo::propose: one live proposal per proposer, found an already pending proposal\"\n );\n }\n\n uint startBlock = add256(block.number, proposalConfigs[uint8(proposalType)].votingDelay);\n uint endBlock = add256(startBlock, proposalConfigs[uint8(proposalType)].votingPeriod);\n\n proposalCount++;\n Proposal memory newProposal = Proposal({\n id: proposalCount,\n proposer: msg.sender,\n eta: 0,\n targets: targets,\n values: values,\n signatures: signatures,\n calldatas: calldatas,\n startBlock: startBlock,\n endBlock: endBlock,\n forVotes: 0,\n againstVotes: 0,\n abstainVotes: 0,\n canceled: false,\n executed: false,\n proposalType: uint8(proposalType)\n });\n\n proposals[newProposal.id] = newProposal;\n latestProposalIds[newProposal.proposer] = newProposal.id;\n\n emit ProposalCreated(\n newProposal.id,\n msg.sender,\n targets,\n values,\n signatures,\n calldatas,\n startBlock,\n endBlock,\n description,\n uint8(proposalType)\n );\n return newProposal.id;\n }\n\n /**\n * @notice Queues a proposal of state succeeded\n * @param proposalId The id of the proposal to queue\n */\n function queue(uint proposalId) external {\n require(\n state(proposalId) == ProposalState.Succeeded,\n \"GovernorBravo::queue: proposal can only be queued if it is succeeded\"\n );\n Proposal storage proposal = proposals[proposalId];\n uint eta = add256(block.timestamp, proposalTimelocks[uint8(proposal.proposalType)].delay());\n for (uint i; i < proposal.targets.length; ++i) {\n queueOrRevertInternal(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n eta,\n uint8(proposal.proposalType)\n );\n }\n proposal.eta = eta;\n emit ProposalQueued(proposalId, eta);\n }\n\n function queueOrRevertInternal(\n address target,\n uint value,\n string memory signature,\n bytes memory data,\n uint eta,\n uint8 proposalType\n ) internal {\n require(\n !proposalTimelocks[proposalType].queuedTransactions(\n keccak256(abi.encode(target, value, signature, data, eta))\n ),\n \"GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta\"\n );\n proposalTimelocks[proposalType].queueTransaction(target, value, signature, data, eta);\n }\n\n /**\n * @notice Executes a queued proposal if eta has passed\n * @param proposalId The id of the proposal to execute\n */\n function execute(uint proposalId) external {\n require(\n state(proposalId) == ProposalState.Queued,\n \"GovernorBravo::execute: proposal can only be executed if it is queued\"\n );\n Proposal storage proposal = proposals[proposalId];\n proposal.executed = true;\n for (uint i; i < proposal.targets.length; ++i) {\n proposalTimelocks[uint8(proposal.proposalType)].executeTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n proposal.eta\n );\n }\n emit ProposalExecuted(proposalId);\n }\n\n /**\n * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold\n * @param proposalId The id of the proposal to cancel\n */\n function cancel(uint proposalId) external {\n require(state(proposalId) != ProposalState.Executed, \"GovernorBravo::cancel: cannot cancel executed proposal\");\n\n Proposal storage proposal = proposals[proposalId];\n require(\n msg.sender == guardian ||\n msg.sender == proposal.proposer ||\n xvsVault.getPriorVotes(proposal.proposer, sub256(block.number, 1)) <\n proposalConfigs[proposal.proposalType].proposalThreshold,\n \"GovernorBravo::cancel: proposer above threshold\"\n );\n\n proposal.canceled = true;\n for (uint i = 0; i < proposal.targets.length; i++) {\n proposalTimelocks[proposal.proposalType].cancelTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n proposal.eta\n );\n }\n\n emit ProposalCanceled(proposalId);\n }\n\n /**\n * @notice Gets actions of a proposal\n * @param proposalId the id of the proposal\n * @return targets, values, signatures, and calldatas of the proposal actions\n */\n function getActions(\n uint proposalId\n )\n external\n view\n returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas)\n {\n Proposal storage p = proposals[proposalId];\n return (p.targets, p.values, p.signatures, p.calldatas);\n }\n\n /**\n * @notice Gets the receipt for a voter on a given proposal\n * @param proposalId the id of proposal\n * @param voter The address of the voter\n * @return The voting receipt\n */\n function getReceipt(uint proposalId, address voter) external view returns (Receipt memory) {\n return proposals[proposalId].receipts[voter];\n }\n\n /**\n * @notice Gets the state of a proposal\n * @param proposalId The id of the proposal\n * @return Proposal state\n */\n function state(uint proposalId) public view returns (ProposalState) {\n require(\n proposalCount >= proposalId && proposalId > initialProposalId,\n \"GovernorBravo::state: invalid proposal id\"\n );\n Proposal storage proposal = proposals[proposalId];\n if (proposal.canceled) {\n return ProposalState.Canceled;\n } else if (block.number <= proposal.startBlock) {\n return ProposalState.Pending;\n } else if (block.number <= proposal.endBlock) {\n return ProposalState.Active;\n } else if (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < quorumVotes) {\n return ProposalState.Defeated;\n } else if (proposal.eta == 0) {\n return ProposalState.Succeeded;\n } else if (proposal.executed) {\n return ProposalState.Executed;\n } else if (\n block.timestamp >= add256(proposal.eta, proposalTimelocks[uint8(proposal.proposalType)].GRACE_PERIOD())\n ) {\n return ProposalState.Expired;\n } else {\n return ProposalState.Queued;\n }\n }\n\n /**\n * @notice Cast a vote for a proposal\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n */\n function castVote(uint proposalId, uint8 support) external {\n emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), \"\");\n }\n\n /**\n * @notice Cast a vote for a proposal with a reason\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @param reason The reason given for the vote by the voter\n */\n function castVoteWithReason(uint proposalId, uint8 support, string calldata reason) external {\n emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), reason);\n }\n\n /**\n * @notice Cast a vote for a proposal by signature\n * @dev External function that accepts EIP-712 signatures for voting on proposals.\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @param v recovery id of ECDSA signature\n * @param r part of the ECDSA sig output\n * @param s part of the ECDSA sig output\n */\n function castVoteBySig(uint proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"GovernorBravo::castVoteBySig: invalid signature\");\n emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), \"\");\n }\n\n /**\n * @notice Internal function that caries out voting logic\n * @param voter The voter that is casting their vote\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @return The number of votes cast\n */\n function castVoteInternal(address voter, uint proposalId, uint8 support) internal returns (uint96) {\n require(state(proposalId) == ProposalState.Active, \"GovernorBravo::castVoteInternal: voting is closed\");\n require(support <= 2, \"GovernorBravo::castVoteInternal: invalid vote type\");\n Proposal storage proposal = proposals[proposalId];\n Receipt storage receipt = proposal.receipts[voter];\n require(receipt.hasVoted == false, \"GovernorBravo::castVoteInternal: voter already voted\");\n uint96 votes = xvsVault.getPriorVotes(voter, proposal.startBlock);\n\n if (support == 0) {\n proposal.againstVotes = add256(proposal.againstVotes, votes);\n } else if (support == 1) {\n proposal.forVotes = add256(proposal.forVotes, votes);\n } else if (support == 2) {\n proposal.abstainVotes = add256(proposal.abstainVotes, votes);\n }\n\n receipt.hasVoted = true;\n receipt.support = support;\n receipt.votes = votes;\n\n return votes;\n }\n\n /**\n * @notice Sets the new governance guardian\n * @param newGuardian the address of the new guardian\n */\n function _setGuardian(address newGuardian) external {\n require(msg.sender == guardian || msg.sender == admin, \"GovernorBravo::_setGuardian: admin or guardian only\");\n require(newGuardian != address(0), \"GovernorBravo::_setGuardian: cannot live without a guardian\");\n address oldGuardian = guardian;\n guardian = newGuardian;\n\n emit NewGuardian(oldGuardian, newGuardian);\n }\n\n /**\n * @notice Initiate the GovernorBravo contract\n * @dev Admin only. Sets initial proposal id which initiates the contract, ensuring a continuous proposal id count\n * @param governorAlpha The address for the Governor to continue the proposal id count from\n */\n function _initiate(address governorAlpha) external {\n require(msg.sender == admin, \"GovernorBravo::_initiate: admin only\");\n require(initialProposalId == 0, \"GovernorBravo::_initiate: can only initiate once\");\n proposalCount = GovernorAlphaInterface(governorAlpha).proposalCount();\n initialProposalId = proposalCount;\n for (uint256 i; i < uint8(ProposalType.CRITICAL) + 1; ++i) {\n proposalTimelocks[i].acceptAdmin();\n }\n }\n\n /**\n * @notice Set max proposal operations\n * @dev Admin only.\n * @param proposalMaxOperations_ Max proposal operations\n */\n function _setProposalMaxOperations(uint proposalMaxOperations_) external {\n require(msg.sender == admin, \"GovernorBravo::_setProposalMaxOperations: admin only\");\n uint oldProposalMaxOperations = proposalMaxOperations;\n proposalMaxOperations = proposalMaxOperations_;\n\n emit ProposalMaxOperationsUpdated(oldProposalMaxOperations, proposalMaxOperations_);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n */\n function _setPendingAdmin(address newPendingAdmin) external {\n // Check caller = admin\n require(msg.sender == admin, \"GovernorBravo:_setPendingAdmin: admin only\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n */\n function _acceptAdmin() external {\n // Check caller is pendingAdmin and pendingAdmin ≠ address(0)\n require(\n msg.sender == pendingAdmin && msg.sender != address(0),\n \"GovernorBravo:_acceptAdmin: pending admin only\"\n );\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n function add256(uint256 a, uint256 b) internal pure returns (uint) {\n uint c = a + b;\n require(c >= a, \"addition overflow\");\n return c;\n }\n\n function sub256(uint256 a, uint256 b) internal pure returns (uint) {\n require(b <= a, \"subtraction underflow\");\n return a - b;\n }\n\n function getChainIdInternal() internal pure returns (uint) {\n uint chainId;\n assembly {\n chainId := chainid()\n }\n return chainId;\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/GovernorBravoInterfaces.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\n/**\n * @title GovernorBravoEvents\n * @author Venus\n * @notice Set of events emitted by the GovernorBravo contracts.\n */\ncontract GovernorBravoEvents {\n /// @notice An event emitted when a new proposal is created\n event ProposalCreated(\n uint id,\n address proposer,\n address[] targets,\n uint[] values,\n string[] signatures,\n bytes[] calldatas,\n uint startBlock,\n uint endBlock,\n string description,\n uint8 proposalType\n );\n\n /// @notice An event emitted when a vote has been cast on a proposal\n /// @param voter The address which casted a vote\n /// @param proposalId The proposal id which was voted on\n /// @param support Support value for the vote. 0=against, 1=for, 2=abstain\n /// @param votes Number of votes which were cast by the voter\n /// @param reason The reason given for the vote by the voter\n event VoteCast(address indexed voter, uint proposalId, uint8 support, uint votes, string reason);\n\n /// @notice An event emitted when a proposal has been canceled\n event ProposalCanceled(uint id);\n\n /// @notice An event emitted when a proposal has been queued in the Timelock\n event ProposalQueued(uint id, uint eta);\n\n /// @notice An event emitted when a proposal has been executed in the Timelock\n event ProposalExecuted(uint id);\n\n /// @notice An event emitted when the voting delay is set\n event VotingDelaySet(uint oldVotingDelay, uint newVotingDelay);\n\n /// @notice An event emitted when the voting period is set\n event VotingPeriodSet(uint oldVotingPeriod, uint newVotingPeriod);\n\n /// @notice Emitted when implementation is changed\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /// @notice Emitted when proposal threshold is set\n event ProposalThresholdSet(uint oldProposalThreshold, uint newProposalThreshold);\n\n /// @notice Emitted when pendingAdmin is changed\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /// @notice Emitted when pendingAdmin is accepted, which means admin is updated\n event NewAdmin(address oldAdmin, address newAdmin);\n\n /// @notice Emitted when the new guardian address is set\n event NewGuardian(address oldGuardian, address newGuardian);\n\n /// @notice Emitted when the maximum number of operations in one proposal is updated\n event ProposalMaxOperationsUpdated(uint oldMaxOperations, uint newMaxOperations);\n}\n\n/**\n * @title GovernorBravoDelegatorStorage\n * @author Venus\n * @notice Storage layout of the `GovernorBravoDelegator` contract\n */\ncontract GovernorBravoDelegatorStorage {\n /// @notice Administrator for this contract\n address public admin;\n\n /// @notice Pending administrator for this contract\n address public pendingAdmin;\n\n /// @notice Active brains of Governor\n address public implementation;\n}\n\n/**\n * @title GovernorBravoDelegateStorageV1\n * @dev For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new\n * contract which implements GovernorBravoDelegateStorageV1 and following the naming convention\n * GovernorBravoDelegateStorageVX.\n */\ncontract GovernorBravoDelegateStorageV1 is GovernorBravoDelegatorStorage {\n /// @notice DEPRECATED The delay before voting on a proposal may take place, once proposed, in blocks\n uint public votingDelay;\n\n /// @notice DEPRECATED The duration of voting on a proposal, in blocks\n uint public votingPeriod;\n\n /// @notice DEPRECATED The number of votes required in order for a voter to become a proposer\n uint public proposalThreshold;\n\n /// @notice Initial proposal id set at become\n uint public initialProposalId;\n\n /// @notice The total number of proposals\n uint public proposalCount;\n\n /// @notice The address of the Venus Protocol Timelock\n TimelockInterface public timelock;\n\n /// @notice The address of the Venus governance token\n XvsVaultInterface public xvsVault;\n\n /// @notice The official record of all proposals ever proposed\n mapping(uint => Proposal) public proposals;\n\n /// @notice The latest proposal for each proposer\n mapping(address => uint) public latestProposalIds;\n\n struct Proposal {\n /// @notice Unique id for looking up a proposal\n uint id;\n /// @notice Creator of the proposal\n address proposer;\n /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds\n uint eta;\n /// @notice the ordered list of target addresses for calls to be made\n address[] targets;\n /// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made\n uint[] values;\n /// @notice The ordered list of function signatures to be called\n string[] signatures;\n /// @notice The ordered list of calldata to be passed to each call\n bytes[] calldatas;\n /// @notice The block at which voting begins: holders must delegate their votes prior to this block\n uint startBlock;\n /// @notice The block at which voting ends: votes must be cast prior to this block\n uint endBlock;\n /// @notice Current number of votes in favor of this proposal\n uint forVotes;\n /// @notice Current number of votes in opposition to this proposal\n uint againstVotes;\n /// @notice Current number of votes for abstaining for this proposal\n uint abstainVotes;\n /// @notice Flag marking whether the proposal has been canceled\n bool canceled;\n /// @notice Flag marking whether the proposal has been executed\n bool executed;\n /// @notice Receipts of ballots for the entire set of voters\n mapping(address => Receipt) receipts;\n /// @notice The type of the proposal\n uint8 proposalType;\n }\n\n /// @notice Ballot receipt record for a voter\n struct Receipt {\n /// @notice Whether or not a vote has been cast\n bool hasVoted;\n /// @notice Whether or not the voter supports the proposal or abstains\n uint8 support;\n /// @notice The number of votes the voter had, which were cast\n uint96 votes;\n }\n\n /// @notice Possible states that a proposal may be in\n enum ProposalState {\n Pending,\n Active,\n Canceled,\n Defeated,\n Succeeded,\n Queued,\n Expired,\n Executed\n }\n\n /// @notice The maximum number of actions that can be included in a proposal\n uint public proposalMaxOperations;\n\n /// @notice A privileged role that can cancel any proposal\n address public guardian;\n}\n\n/**\n * @title GovernorBravoDelegateStorageV2\n * @dev For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new\n * contract which implements GovernorBravoDelegateStorageV2 and following the naming convention\n * GovernorBravoDelegateStorageVX.\n */\ncontract GovernorBravoDelegateStorageV2 is GovernorBravoDelegateStorageV1 {\n enum ProposalType {\n NORMAL,\n FASTTRACK,\n CRITICAL\n }\n\n struct ProposalConfig {\n /// @notice The delay before voting on a proposal may take place, once proposed, in blocks\n uint256 votingDelay;\n /// @notice The duration of voting on a proposal, in blocks\n uint256 votingPeriod;\n /// @notice The number of votes required in order for a voter to become a proposer\n uint256 proposalThreshold;\n }\n\n /// @notice mapping containing configuration for each proposal type\n mapping(uint => ProposalConfig) public proposalConfigs;\n\n /// @notice mapping containing Timelock addresses for each proposal type\n mapping(uint => TimelockInterface) public proposalTimelocks;\n}\n\n/**\n * @title TimelockInterface\n * @author Venus\n * @notice Interface implemented by the Timelock contract.\n */\ninterface TimelockInterface {\n function delay() external view returns (uint);\n\n function GRACE_PERIOD() external view returns (uint);\n\n function acceptAdmin() external;\n\n function queuedTransactions(bytes32 hash) external view returns (bool);\n\n function queueTransaction(\n address target,\n uint value,\n string calldata signature,\n bytes calldata data,\n uint eta\n ) external returns (bytes32);\n\n function cancelTransaction(\n address target,\n uint value,\n string calldata signature,\n bytes calldata data,\n uint eta\n ) external;\n\n function executeTransaction(\n address target,\n uint value,\n string calldata signature,\n bytes calldata data,\n uint eta\n ) external payable returns (bytes memory);\n}\n\ninterface XvsVaultInterface {\n function getPriorVotes(address account, uint blockNumber) external view returns (uint96);\n}\n\ninterface GovernorAlphaInterface {\n /// @notice The total number of proposals\n function proposalCount() external returns (uint);\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.5.16;\n\n/**\n * @title IAccessControlManagerV5\n * @author Venus\n * @notice Interface implemented by the `AccessControlManagerV5` contract.\n */\ninterface IAccessControlManagerV5 {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n\n /**\n * @notice Gives a function call permission to one single account\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n * \t\tMay emit a {RoleGranted} event.\n * @param contractAddress address of contract for which call permissions will be granted\n * @param functionSig signature e.g. \"functionName(uint,bool)\"\n */\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\n\n /**\n * @notice Revokes an account's permission to a particular function call\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n * \t\tMay emit a {RoleRevoked} event.\n * @param contractAddress address of contract for which call permissions will be revoked\n * @param functionSig signature e.g. \"functionName(uint,bool)\"\n */\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) external;\n\n /**\n * @notice Verifies if the given account can call a praticular contract's function\n * @dev Since the contract is calling itself this function, we can get contracts address with msg.sender\n * @param account address (eoa or contract) for which call permissions will be checked\n * @param functionSig signature e.g. \"functionName(uint,bool)\"\n * @return false if the user account cannot call the particular contract function\n *\n */\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\n\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) external view returns (bool);\n}\n" + }, + "@venusprotocol/solidity-utilities/contracts/TimeManagerV5.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.5.16;\n\ncontract TimeManagerV5 {\n /// @dev The approximate number of seconds per year\n uint256 public constant SECONDS_PER_YEAR = 31_536_000;\n\n /// @notice Number of blocks per year or seconds per year\n uint256 public blocksOrSecondsPerYear;\n\n /// @dev Sets true when block timestamp is used\n bool public isTimeBased;\n\n /// @dev Sets true when contract is initialized\n bool private isInitialized;\n\n /**\n * @dev Retrieves the current slot\n * @return Current slot\n */\n function() view returns (uint256) private _getCurrentSlot;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n\n /**\n * @dev Function to simply retrieve block number or block timestamp\n * @return Current block number or block timestamp\n */\n function getBlockNumberOrTimestamp() public view returns (uint256) {\n return _getCurrentSlot();\n }\n\n /**\n * @dev Initializes the contract to use either blocks or seconds\n * @param timeBased_ A boolean indicating whether the contract is based on time or block\n * If timeBased is true than blocksPerYear_ param is ignored as blocksOrSecondsPerYear is set to SECONDS_PER_YEAR\n * @param blocksPerYear_ The number of blocks per year\n */\n function _initializeTimeManager(bool timeBased_, uint256 blocksPerYear_) internal {\n if (isInitialized) revert(\"Already initialized TimeManager\");\n\n if (!timeBased_ && blocksPerYear_ == 0) {\n revert(\"Invalid blocks per year\");\n }\n if (timeBased_ && blocksPerYear_ != 0) {\n revert(\"Invalid time based configuration\");\n }\n\n isTimeBased = timeBased_;\n blocksOrSecondsPerYear = timeBased_ ? SECONDS_PER_YEAR : blocksPerYear_;\n _getCurrentSlot = timeBased_ ? _getBlockTimestamp : _getBlockNumber;\n isInitialized = true;\n }\n\n /**\n * @dev Returns the current timestamp in seconds\n * @return The current timestamp\n */\n function _getBlockTimestamp() private view returns (uint256) {\n return block.timestamp;\n }\n\n /**\n * @dev Returns the current block number\n * @return The current block number\n */\n function _getBlockNumber() private view returns (uint256) {\n return block.number;\n }\n}\n" + }, + "contracts/Comptroller/ComptrollerInterface.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VToken.sol\";\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Tokens/VAI/VAIControllerInterface.sol\";\nimport { ComptrollerTypes } from \"./ComptrollerStorage.sol\";\n\ncontract ComptrollerInterface {\n /// @notice Indicator that this is a Comptroller contract (for inspection)\n bool public constant isComptroller = true;\n\n /*** Assets You Are In ***/\n\n function enterMarkets(address[] calldata vTokens) external returns (uint[] memory);\n\n function exitMarket(address vToken) external returns (uint);\n\n /*** Policy Hooks ***/\n\n function mintAllowed(address vToken, address minter, uint mintAmount) external returns (uint);\n\n function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\n\n function redeemAllowed(address vToken, address redeemer, uint redeemTokens) external returns (uint);\n\n function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\n\n function borrowAllowed(address vToken, address borrower, uint borrowAmount) external returns (uint);\n\n function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\n\n function repayBorrowAllowed(\n address vToken,\n address payer,\n address borrower,\n uint repayAmount\n ) external returns (uint);\n\n function repayBorrowVerify(\n address vToken,\n address payer,\n address borrower,\n uint repayAmount,\n uint borrowerIndex\n ) external;\n\n function liquidateBorrowAllowed(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint repayAmount\n ) external returns (uint);\n\n function liquidateBorrowVerify(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint repayAmount,\n uint seizeTokens\n ) external;\n\n function seizeAllowed(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint seizeTokens\n ) external returns (uint);\n\n function seizeVerify(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint seizeTokens\n ) external;\n\n function transferAllowed(address vToken, address src, address dst, uint transferTokens) external returns (uint);\n\n function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\n\n /*** Liquidity/Liquidation Calculations ***/\n\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint repayAmount\n ) external view returns (uint, uint);\n\n function setMintedVAIOf(address owner, uint amount) external returns (uint);\n\n function liquidateVAICalculateSeizeTokens(\n address vTokenCollateral,\n uint repayAmount\n ) external view returns (uint, uint);\n\n function getXVSAddress() public view returns (address);\n\n function markets(address) external view returns (bool, uint);\n\n function oracle() external view returns (PriceOracle);\n\n function getAccountLiquidity(address) external view returns (uint, uint, uint);\n\n function getAssetsIn(address) external view returns (VToken[] memory);\n\n function claimVenus(address) external;\n\n function venusAccrued(address) external view returns (uint);\n\n function venusSupplySpeeds(address) external view returns (uint);\n\n function venusBorrowSpeeds(address) external view returns (uint);\n\n function getAllMarkets() external view returns (VToken[] memory);\n\n function venusSupplierIndex(address, address) external view returns (uint);\n\n function venusInitialIndex() external view returns (uint224);\n\n function venusBorrowerIndex(address, address) external view returns (uint);\n\n function venusBorrowState(address) external view returns (uint224, uint32);\n\n function venusSupplyState(address) external view returns (uint224, uint32);\n\n function approvedDelegates(address borrower, address delegate) external view returns (bool);\n\n function vaiController() external view returns (VAIControllerInterface);\n\n function liquidationIncentiveMantissa() external view returns (uint);\n\n function protocolPaused() external view returns (bool);\n\n function actionPaused(address market, ComptrollerTypes.Action action) public view returns (bool);\n\n function mintedVAIs(address user) external view returns (uint);\n\n function vaiMintRate() external view returns (uint);\n}\n\ninterface IVAIVault {\n function updatePendingRewards() external;\n}\n\ninterface IComptroller {\n function liquidationIncentiveMantissa() external view returns (uint);\n\n /*** Treasury Data ***/\n function treasuryAddress() external view returns (address);\n\n function treasuryPercent() external view returns (uint);\n}\n" + }, + "contracts/Comptroller/ComptrollerLensInterface.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Tokens/VTokens/VToken.sol\";\n\ninterface ComptrollerLensInterface {\n function liquidateCalculateSeizeTokens(\n address comptroller,\n address vTokenBorrowed,\n address vTokenCollateral,\n uint actualRepayAmount\n ) external view returns (uint, uint);\n\n function liquidateVAICalculateSeizeTokens(\n address comptroller,\n address vTokenCollateral,\n uint actualRepayAmount\n ) external view returns (uint, uint);\n\n function getHypotheticalAccountLiquidity(\n address comptroller,\n address account,\n VToken vTokenModify,\n uint redeemTokens,\n uint borrowAmount\n ) external view returns (uint, uint, uint);\n}\n" + }, + "contracts/Comptroller/ComptrollerStorage.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity ^0.5.16;\n\nimport { VToken } from \"../Tokens/VTokens/VToken.sol\";\nimport { PriceOracle } from \"../Oracle/PriceOracle.sol\";\nimport { VAIControllerInterface } from \"../Tokens/VAI/VAIControllerInterface.sol\";\nimport { ComptrollerLensInterface } from \"./ComptrollerLensInterface.sol\";\nimport { IPrime } from \"../Tokens/Prime/IPrime.sol\";\n\ninterface ComptrollerTypes {\n enum Action {\n MINT,\n REDEEM,\n BORROW,\n REPAY,\n SEIZE,\n LIQUIDATE,\n TRANSFER,\n ENTER_MARKET,\n EXIT_MARKET\n }\n}\n\ncontract UnitrollerAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of Unitroller\n */\n address public comptrollerImplementation;\n\n /**\n * @notice Pending brains of Unitroller\n */\n address public pendingComptrollerImplementation;\n}\n\ncontract ComptrollerV1Storage is ComptrollerTypes, UnitrollerAdminStorage {\n /**\n * @notice Oracle which gives the price of any given asset\n */\n PriceOracle public oracle;\n\n /**\n * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\n */\n uint256 public closeFactorMantissa;\n\n /**\n * @notice Multiplier representing the discount on collateral that a liquidator receives\n */\n uint256 public liquidationIncentiveMantissa;\n\n /**\n * @notice Max number of assets a single account can participate in (borrow or use as collateral)\n */\n uint256 public maxAssets;\n\n /**\n * @notice Per-account mapping of \"assets you are in\", capped by maxAssets\n */\n mapping(address => VToken[]) public accountAssets;\n\n struct Market {\n /// @notice Whether or not this market is listed\n bool isListed;\n /**\n * @notice Multiplier representing the most one can borrow against their collateral in this market.\n * For instance, 0.9 to allow borrowing 90% of collateral value.\n * Must be between 0 and 1, and stored as a mantissa.\n */\n uint256 collateralFactorMantissa;\n /// @notice Per-market mapping of \"accounts in this asset\"\n mapping(address => bool) accountMembership;\n /// @notice Whether or not this market receives XVS\n bool isVenus;\n }\n\n /**\n * @notice Official mapping of vTokens -> Market metadata\n * @dev Used e.g. to determine if a market is supported\n */\n mapping(address => Market) public markets;\n\n /**\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\n */\n address public pauseGuardian;\n\n /// @notice Whether minting is paused (deprecated, superseded by actionPaused)\n bool private _mintGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n bool private _borrowGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n bool internal transferGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n bool internal seizeGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n mapping(address => bool) internal mintGuardianPaused;\n /// @notice Whether borrowing is paused (deprecated, superseded by actionPaused)\n mapping(address => bool) internal borrowGuardianPaused;\n\n struct VenusMarketState {\n /// @notice The market's last updated venusBorrowIndex or venusSupplyIndex\n uint224 index;\n /// @notice The block number the index was last updated at\n uint32 block;\n }\n\n /// @notice A list of all markets\n VToken[] public allMarkets;\n\n /// @notice The rate at which the flywheel distributes XVS, per block\n uint256 internal venusRate;\n\n /// @notice The portion of venusRate that each market currently receives\n mapping(address => uint256) internal venusSpeeds;\n\n /// @notice The Venus market supply state for each market\n mapping(address => VenusMarketState) public venusSupplyState;\n\n /// @notice The Venus market borrow state for each market\n mapping(address => VenusMarketState) public venusBorrowState;\n\n /// @notice The Venus supply index for each market for each supplier as of the last time they accrued XVS\n mapping(address => mapping(address => uint256)) public venusSupplierIndex;\n\n /// @notice The Venus borrow index for each market for each borrower as of the last time they accrued XVS\n mapping(address => mapping(address => uint256)) public venusBorrowerIndex;\n\n /// @notice The XVS accrued but not yet transferred to each user\n mapping(address => uint256) public venusAccrued;\n\n /// @notice The Address of VAIController\n VAIControllerInterface public vaiController;\n\n /// @notice The minted VAI amount to each user\n mapping(address => uint256) public mintedVAIs;\n\n /// @notice VAI Mint Rate as a percentage\n uint256 public vaiMintRate;\n\n /**\n * @notice The Pause Guardian can pause certain actions as a safety mechanism.\n */\n bool public mintVAIGuardianPaused;\n bool public repayVAIGuardianPaused;\n\n /**\n * @notice Pause/Unpause whole protocol actions\n */\n bool public protocolPaused;\n\n /// @notice The rate at which the flywheel distributes XVS to VAI Minters, per block (deprecated)\n uint256 private venusVAIRate;\n}\n\ncontract ComptrollerV2Storage is ComptrollerV1Storage {\n /// @notice The rate at which the flywheel distributes XVS to VAI Vault, per block\n uint256 public venusVAIVaultRate;\n\n // address of VAI Vault\n address public vaiVaultAddress;\n\n // start block of release to VAI Vault\n uint256 public releaseStartBlock;\n\n // minimum release amount to VAI Vault\n uint256 public minReleaseAmount;\n}\n\ncontract ComptrollerV3Storage is ComptrollerV2Storage {\n /// @notice The borrowCapGuardian can set borrowCaps to any number for any market. Lowering the borrow cap could disable borrowing on the given market.\n address public borrowCapGuardian;\n\n /// @notice Borrow caps enforced by borrowAllowed for each vToken address.\n mapping(address => uint256) public borrowCaps;\n}\n\ncontract ComptrollerV4Storage is ComptrollerV3Storage {\n /// @notice Treasury Guardian address\n address public treasuryGuardian;\n\n /// @notice Treasury address\n address public treasuryAddress;\n\n /// @notice Fee percent of accrued interest with decimal 18\n uint256 public treasuryPercent;\n}\n\ncontract ComptrollerV5Storage is ComptrollerV4Storage {\n /// @notice The portion of XVS that each contributor receives per block (deprecated)\n mapping(address => uint256) private venusContributorSpeeds;\n\n /// @notice Last block at which a contributor's XVS rewards have been allocated (deprecated)\n mapping(address => uint256) private lastContributorBlock;\n}\n\ncontract ComptrollerV6Storage is ComptrollerV5Storage {\n address public liquidatorContract;\n}\n\ncontract ComptrollerV7Storage is ComptrollerV6Storage {\n ComptrollerLensInterface public comptrollerLens;\n}\n\ncontract ComptrollerV8Storage is ComptrollerV7Storage {\n /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting notAllowed\n mapping(address => uint256) public supplyCaps;\n}\n\ncontract ComptrollerV9Storage is ComptrollerV8Storage {\n /// @notice AccessControlManager address\n address internal accessControl;\n\n /// @notice True if a certain action is paused on a certain market\n mapping(address => mapping(uint256 => bool)) internal _actionPaused;\n}\n\ncontract ComptrollerV10Storage is ComptrollerV9Storage {\n /// @notice The rate at which venus is distributed to the corresponding borrow market (per block)\n mapping(address => uint256) public venusBorrowSpeeds;\n\n /// @notice The rate at which venus is distributed to the corresponding supply market (per block)\n mapping(address => uint256) public venusSupplySpeeds;\n}\n\ncontract ComptrollerV11Storage is ComptrollerV10Storage {\n /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\n //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\n mapping(address => mapping(address => bool)) public approvedDelegates;\n}\n\ncontract ComptrollerV12Storage is ComptrollerV11Storage {\n /// @notice Whether forced liquidation is enabled for all users borrowing in a certain market\n mapping(address => bool) public isForcedLiquidationEnabled;\n}\n\ncontract ComptrollerV13Storage is ComptrollerV12Storage {\n struct FacetAddressAndPosition {\n address facetAddress;\n uint96 functionSelectorPosition; // position in _facetFunctionSelectors.functionSelectors array\n }\n\n struct FacetFunctionSelectors {\n bytes4[] functionSelectors;\n uint256 facetAddressPosition; // position of facetAddress in _facetAddresses array\n }\n\n mapping(bytes4 => FacetAddressAndPosition) internal _selectorToFacetAndPosition;\n // maps facet addresses to function selectors\n mapping(address => FacetFunctionSelectors) internal _facetFunctionSelectors;\n // facet addresses\n address[] internal _facetAddresses;\n}\n\ncontract ComptrollerV14Storage is ComptrollerV13Storage {\n /// @notice Prime token address\n IPrime public prime;\n}\n\ncontract ComptrollerV15Storage is ComptrollerV14Storage {\n /// @notice Whether forced liquidation is enabled for the borrows of a user in a market\n mapping(address /* user */ => mapping(address /* market */ => bool)) public isForcedLiquidationEnabledForUser;\n}\n\ncontract ComptrollerV16Storage is ComptrollerV15Storage {\n /// @notice The XVS token contract address\n address internal xvs;\n\n /// @notice The XVS vToken contract address\n address internal xvsVToken;\n}\n" + }, + "contracts/Comptroller/Diamond/Diamond.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\npragma experimental ABIEncoderV2;\n\nimport { IDiamondCut } from \"./interfaces/IDiamondCut.sol\";\nimport { Unitroller, ComptrollerV16Storage } from \"../Unitroller.sol\";\n\n/**\n * @title Diamond\n * @author Venus\n * @notice This contract contains functions related to facets\n */\ncontract Diamond is IDiamondCut, ComptrollerV16Storage {\n /// @notice Emitted when functions are added, replaced or removed to facets\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut);\n\n struct Facet {\n address facetAddress;\n bytes4[] functionSelectors;\n }\n\n /**\n * @notice Call _acceptImplementation to accept the diamond proxy as new implementaion\n * @param unitroller Address of the unitroller\n */\n function _become(Unitroller unitroller) public {\n require(msg.sender == unitroller.admin(), \"only unitroller admin can\");\n require(unitroller._acceptImplementation() == 0, \"not authorized\");\n }\n\n /**\n * @notice To add function selectors to the facet's mapping\n * @dev Allows the contract admin to add function selectors\n * @param diamondCut_ IDiamondCut contains facets address, action and function selectors\n */\n function diamondCut(IDiamondCut.FacetCut[] memory diamondCut_) public {\n require(msg.sender == admin, \"only unitroller admin can\");\n libDiamondCut(diamondCut_);\n }\n\n /**\n * @notice Get all function selectors mapped to the facet address\n * @param facet Address of the facet\n * @return selectors Array of function selectors\n */\n function facetFunctionSelectors(address facet) external view returns (bytes4[] memory) {\n return _facetFunctionSelectors[facet].functionSelectors;\n }\n\n /**\n * @notice Get facet position in the _facetFunctionSelectors through facet address\n * @param facet Address of the facet\n * @return Position of the facet\n */\n function facetPosition(address facet) external view returns (uint256) {\n return _facetFunctionSelectors[facet].facetAddressPosition;\n }\n\n /**\n * @notice Get all facet addresses\n * @return facetAddresses Array of facet addresses\n */\n function facetAddresses() external view returns (address[] memory) {\n return _facetAddresses;\n }\n\n /**\n * @notice Get facet address and position through function selector\n * @param functionSelector function selector\n * @return FacetAddressAndPosition facet address and position\n */\n function facetAddress(\n bytes4 functionSelector\n ) external view returns (ComptrollerV16Storage.FacetAddressAndPosition memory) {\n return _selectorToFacetAndPosition[functionSelector];\n }\n\n /**\n * @notice Get all facets address and their function selector\n * @return facets_ Array of Facet\n */\n function facets() external view returns (Facet[] memory) {\n uint256 facetsLength = _facetAddresses.length;\n Facet[] memory facets_ = new Facet[](facetsLength);\n for (uint256 i; i < facetsLength; ++i) {\n address facet = _facetAddresses[i];\n facets_[i].facetAddress = facet;\n facets_[i].functionSelectors = _facetFunctionSelectors[facet].functionSelectors;\n }\n return facets_;\n }\n\n /**\n * @notice To add function selectors to the facets' mapping\n * @param diamondCut_ IDiamondCut contains facets address, action and function selectors\n */\n function libDiamondCut(IDiamondCut.FacetCut[] memory diamondCut_) internal {\n uint256 diamondCutLength = diamondCut_.length;\n for (uint256 facetIndex; facetIndex < diamondCutLength; ++facetIndex) {\n IDiamondCut.FacetCutAction action = diamondCut_[facetIndex].action;\n if (action == IDiamondCut.FacetCutAction.Add) {\n addFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\n replaceFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\n removeFunctions(diamondCut_[facetIndex].facetAddress, diamondCut_[facetIndex].functionSelectors);\n } else {\n revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n }\n }\n emit DiamondCut(diamondCut_);\n }\n\n /**\n * @notice Add function selectors to the facet's address mapping\n * @param facetAddress Address of the facet\n * @param functionSelectors Array of function selectors need to add in the mapping\n */\n function addFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {\n require(functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n require(facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(_facetFunctionSelectors[facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(facetAddress);\n }\n uint256 functionSelectorsLength = functionSelectors.length;\n for (uint256 selectorIndex; selectorIndex < functionSelectorsLength; ++selectorIndex) {\n bytes4 selector = functionSelectors[selectorIndex];\n address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n addFunction(selector, selectorPosition, facetAddress);\n ++selectorPosition;\n }\n }\n\n /**\n * @notice Replace facet's address mapping for function selectors i.e selectors already associate to any other existing facet\n * @param facetAddress Address of the facet\n * @param functionSelectors Array of function selectors need to replace in the mapping\n */\n function replaceFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {\n require(functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n require(facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n uint96 selectorPosition = uint96(_facetFunctionSelectors[facetAddress].functionSelectors.length);\n // add new facet address if it does not exist\n if (selectorPosition == 0) {\n addFacet(facetAddress);\n }\n uint256 functionSelectorsLength = functionSelectors.length;\n for (uint256 selectorIndex; selectorIndex < functionSelectorsLength; ++selectorIndex) {\n bytes4 selector = functionSelectors[selectorIndex];\n address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress;\n require(oldFacetAddress != facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n removeFunction(oldFacetAddress, selector);\n addFunction(selector, selectorPosition, facetAddress);\n ++selectorPosition;\n }\n }\n\n /**\n * @notice Remove function selectors to the facet's address mapping\n * @param facetAddress Address of the facet\n * @param functionSelectors Array of function selectors need to remove in the mapping\n */\n function removeFunctions(address facetAddress, bytes4[] memory functionSelectors) internal {\n uint256 functionSelectorsLength = functionSelectors.length;\n require(functionSelectorsLength != 0, \"LibDiamondCut: No selectors in facet to cut\");\n // if function does not exist then do nothing and revert\n require(facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n for (uint256 selectorIndex; selectorIndex < functionSelectorsLength; ++selectorIndex) {\n bytes4 selector = functionSelectors[selectorIndex];\n address oldFacetAddress = _selectorToFacetAndPosition[selector].facetAddress;\n removeFunction(oldFacetAddress, selector);\n }\n }\n\n /**\n * @notice Add new facet to the proxy\n * @param facetAddress Address of the facet\n */\n function addFacet(address facetAddress) internal {\n enforceHasContractCode(facetAddress, \"Diamond: New facet has no code\");\n _facetFunctionSelectors[facetAddress].facetAddressPosition = _facetAddresses.length;\n _facetAddresses.push(facetAddress);\n }\n\n /**\n * @notice Add function selector to the facet's address mapping\n * @param selector funciton selector need to be added\n * @param selectorPosition funciton selector position\n * @param facetAddress Address of the facet\n */\n function addFunction(bytes4 selector, uint96 selectorPosition, address facetAddress) internal {\n _selectorToFacetAndPosition[selector].functionSelectorPosition = selectorPosition;\n _facetFunctionSelectors[facetAddress].functionSelectors.push(selector);\n _selectorToFacetAndPosition[selector].facetAddress = facetAddress;\n }\n\n /**\n * @notice Remove function selector to the facet's address mapping\n * @param facetAddress Address of the facet\n * @param selector function selectors need to remove in the mapping\n */\n function removeFunction(address facetAddress, bytes4 selector) internal {\n require(facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n\n // replace selector with last selector, then delete last selector\n uint256 selectorPosition = _selectorToFacetAndPosition[selector].functionSelectorPosition;\n uint256 lastSelectorPosition = _facetFunctionSelectors[facetAddress].functionSelectors.length - 1;\n // if not the same then replace selector with lastSelector\n if (selectorPosition != lastSelectorPosition) {\n bytes4 lastSelector = _facetFunctionSelectors[facetAddress].functionSelectors[lastSelectorPosition];\n _facetFunctionSelectors[facetAddress].functionSelectors[selectorPosition] = lastSelector;\n _selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n }\n // delete the last selector\n _facetFunctionSelectors[facetAddress].functionSelectors.pop();\n delete _selectorToFacetAndPosition[selector];\n\n // if no more selectors for facet address then delete the facet address\n if (lastSelectorPosition == 0) {\n // replace facet address with last facet address and delete last facet address\n uint256 lastFacetAddressPosition = _facetAddresses.length - 1;\n uint256 facetAddressPosition = _facetFunctionSelectors[facetAddress].facetAddressPosition;\n if (facetAddressPosition != lastFacetAddressPosition) {\n address lastFacetAddress = _facetAddresses[lastFacetAddressPosition];\n _facetAddresses[facetAddressPosition] = lastFacetAddress;\n _facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n }\n _facetAddresses.pop();\n delete _facetFunctionSelectors[facetAddress];\n }\n }\n\n /**\n * @dev Ensure that the given address has contract code deployed\n * @param _contract The address to check for contract code\n * @param _errorMessage The error message to display if the contract code is not deployed\n */\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n uint256 contractSize;\n assembly {\n contractSize := extcodesize(_contract)\n }\n require(contractSize != 0, _errorMessage);\n }\n\n // Find facet for function that is called and execute the\n // function if a facet is found and return any value.\n function() external payable {\n address facet = _selectorToFacetAndPosition[msg.sig].facetAddress;\n require(facet != address(0), \"Diamond: Function does not exist\");\n // Execute public function from facet using delegatecall and return any value.\n assembly {\n // copy function selector and any arguments\n calldatacopy(0, 0, calldatasize())\n // execute function call using the facet\n let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n // get any return value\n returndatacopy(0, 0, returndatasize())\n // return any return value or error back to the caller\n switch result\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n}\n" + }, + "contracts/Comptroller/Diamond/DiamondConsolidated.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"./facets/MarketFacet.sol\";\nimport \"./facets/PolicyFacet.sol\";\nimport \"./facets/RewardFacet.sol\";\nimport \"./facets/SetterFacet.sol\";\nimport \"./Diamond.sol\";\n\n/**\n * @title DiamondConsolidated\n * @author Venus\n * @notice This contract contains the functions defined in the different facets of the Diamond, plus the getters to the public variables.\n * This contract cannot be deployed, due to its size. Its main purpose is to allow the easy generation of an ABI and the typechain to interact with the\n * Unitroller contract in a simple way\n */\ncontract DiamondConsolidated is Diamond, MarketFacet, PolicyFacet, RewardFacet, SetterFacet {}\n" + }, + "contracts/Comptroller/Diamond/facets/FacetBase.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken, ComptrollerErrorReporter, ExponentialNoError } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { IVAIVault } from \"../../../Comptroller/ComptrollerInterface.sol\";\nimport { ComptrollerV16Storage } from \"../../../Comptroller/ComptrollerStorage.sol\";\nimport { IAccessControlManagerV5 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\";\n\nimport { SafeBEP20, IBEP20 } from \"../../../Utils/SafeBEP20.sol\";\n\n/**\n * @title FacetBase\n * @author Venus\n * @notice This facet contract contains functions related to access and checks\n */\ncontract FacetBase is ComptrollerV16Storage, ExponentialNoError, ComptrollerErrorReporter {\n using SafeBEP20 for IBEP20;\n\n /// @notice The initial Venus index for a market\n uint224 public constant venusInitialIndex = 1e36;\n // closeFactorMantissa must be strictly greater than this value\n uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05\n // closeFactorMantissa must not exceed this value\n uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9\n // No collateralFactorMantissa may exceed this value\n uint256 internal constant collateralFactorMaxMantissa = 0.9e18; // 0.9\n\n /// @notice Emitted when an account enters a market\n event MarketEntered(VToken indexed vToken, address indexed account);\n\n /// @notice Emitted when XVS is distributed to VAI Vault\n event DistributedVAIVaultVenus(uint256 amount);\n\n /// @notice Reverts if the protocol is paused\n function checkProtocolPauseState() internal view {\n require(!protocolPaused, \"protocol is paused\");\n }\n\n /// @notice Reverts if a certain action is paused on a market\n function checkActionPauseState(address market, Action action) internal view {\n require(!actionPaused(market, action), \"action is paused\");\n }\n\n /// @notice Reverts if the caller is not admin\n function ensureAdmin() internal view {\n require(msg.sender == admin, \"only admin can\");\n }\n\n /// @notice Checks the passed address is nonzero\n function ensureNonzeroAddress(address someone) internal pure {\n require(someone != address(0), \"can't be zero address\");\n }\n\n /// @notice Reverts if the market is not listed\n function ensureListed(Market storage market) internal view {\n require(market.isListed, \"market not listed\");\n }\n\n /// @notice Reverts if the caller is neither admin nor the passed address\n function ensureAdminOr(address privilegedAddress) internal view {\n require(msg.sender == admin || msg.sender == privilegedAddress, \"access denied\");\n }\n\n /// @notice Checks the caller is allowed to call the specified fuction\n function ensureAllowed(string memory functionSig) internal view {\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \"access denied\");\n }\n\n /**\n * @notice Checks if a certain action is paused on a market\n * @param action Action id\n * @param market vToken address\n */\n function actionPaused(address market, Action action) public view returns (bool) {\n return _actionPaused[market][uint256(action)];\n }\n\n /**\n * @notice Get the latest block number\n */\n function getBlockNumber() internal view returns (uint256) {\n return block.number;\n }\n\n /**\n * @notice Get the latest block number with the safe32 check\n */\n function getBlockNumberAsUint32() internal view returns (uint32) {\n return safe32(getBlockNumber(), \"block # > 32 bits\");\n }\n\n /**\n * @notice Transfer XVS to VAI Vault\n */\n function releaseToVault() internal {\n if (releaseStartBlock == 0 || getBlockNumber() < releaseStartBlock) {\n return;\n }\n\n IBEP20 xvs_ = IBEP20(xvs);\n\n uint256 xvsBalance = xvs_.balanceOf(address(this));\n if (xvsBalance == 0) {\n return;\n }\n\n uint256 actualAmount;\n uint256 deltaBlocks = sub_(getBlockNumber(), releaseStartBlock);\n // releaseAmount = venusVAIVaultRate * deltaBlocks\n uint256 releaseAmount_ = mul_(venusVAIVaultRate, deltaBlocks);\n\n if (xvsBalance >= releaseAmount_) {\n actualAmount = releaseAmount_;\n } else {\n actualAmount = xvsBalance;\n }\n\n if (actualAmount < minReleaseAmount) {\n return;\n }\n\n releaseStartBlock = getBlockNumber();\n\n xvs_.safeTransfer(vaiVaultAddress, actualAmount);\n emit DistributedVAIVaultVenus(actualAmount);\n\n IVAIVault(vaiVaultAddress).updatePendingRewards();\n }\n\n /**\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\n * @param vTokenModify The market to hypothetically redeem/borrow in\n * @param account The account to determine liquidity for\n * @param redeemTokens The number of tokens to hypothetically redeem\n * @param borrowAmount The amount of underlying to hypothetically borrow\n * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\n * without calculating accumulated interest.\n * @return (possible error code,\n hypothetical account liquidity in excess of collateral requirements,\n * hypothetical account shortfall below collateral requirements)\n */\n function getHypotheticalAccountLiquidityInternal(\n address account,\n VToken vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n ) internal view returns (Error, uint256, uint256) {\n (uint256 err, uint256 liquidity, uint256 shortfall) = comptrollerLens.getHypotheticalAccountLiquidity(\n address(this),\n account,\n vTokenModify,\n redeemTokens,\n borrowAmount\n );\n return (Error(err), liquidity, shortfall);\n }\n\n /**\n * @notice Add the market to the borrower's \"assets in\" for liquidity calculations\n * @param vToken The market to enter\n * @param borrower The address of the account to modify\n * @return Success indicator for whether the market was entered\n */\n function addToMarketInternal(VToken vToken, address borrower) internal returns (Error) {\n checkActionPauseState(address(vToken), Action.ENTER_MARKET);\n Market storage marketToJoin = markets[address(vToken)];\n ensureListed(marketToJoin);\n if (marketToJoin.accountMembership[borrower]) {\n // already joined\n return Error.NO_ERROR;\n }\n // survived the gauntlet, add to list\n // NOTE: we store these somewhat redundantly as a significant optimization\n // this avoids having to iterate through the list for the most common use cases\n // that is, only when we need to perform liquidity checks\n // and not whenever we want to check if an account is in a particular market\n marketToJoin.accountMembership[borrower] = true;\n accountAssets[borrower].push(vToken);\n\n emit MarketEntered(vToken, borrower);\n\n return Error.NO_ERROR;\n }\n\n /**\n * @notice Checks for the user is allowed to redeem tokens\n * @param vToken Address of the market\n * @param redeemer Address of the user\n * @param redeemTokens Amount of tokens to redeem\n * @return Success indicator for redeem is allowed or not\n */\n function redeemAllowedInternal(\n address vToken,\n address redeemer,\n uint256 redeemTokens\n ) internal view returns (uint256) {\n ensureListed(markets[vToken]);\n /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\n if (!markets[vToken].accountMembership[redeemer]) {\n return uint256(Error.NO_ERROR);\n }\n /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\n redeemer,\n VToken(vToken),\n redeemTokens,\n 0\n );\n if (err != Error.NO_ERROR) {\n return uint256(err);\n }\n if (shortfall != 0) {\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\n }\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Returns the XVS address\n * @return The address of XVS token\n */\n function getXVSAddress() external view returns (address) {\n return xvs;\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/MarketFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { IMarketFacet } from \"../interfaces/IMarketFacet.sol\";\nimport { FacetBase } from \"./FacetBase.sol\";\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\n\n/**\n * @title MarketFacet\n * @author Venus\n * @dev This facet contains all the methods related to the market's management in the pool\n * @notice This facet contract contains functions regarding markets\n */\ncontract MarketFacet is IMarketFacet, FacetBase {\n /// @notice Emitted when an admin supports a market\n event MarketListed(VToken indexed vToken);\n\n /// @notice Emitted when an account exits a market\n event MarketExited(VToken indexed vToken, address indexed account);\n\n /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account\n event DelegateUpdated(address indexed approver, address indexed delegate, bool approved);\n\n /// @notice Emitted when an admin unlists a market\n event MarketUnlisted(address indexed vToken);\n\n /// @notice Indicator that this is a Comptroller contract (for inspection)\n function isComptroller() public pure returns (bool) {\n return true;\n }\n\n /**\n * @notice Returns the assets an account has entered\n * @param account The address of the account to pull assets for\n * @return A dynamic list with the assets the account has entered\n */\n function getAssetsIn(address account) external view returns (VToken[] memory) {\n uint256 len;\n VToken[] memory _accountAssets = accountAssets[account];\n uint256 _accountAssetsLength = _accountAssets.length;\n\n VToken[] memory assetsIn = new VToken[](_accountAssetsLength);\n\n for (uint256 i; i < _accountAssetsLength; ++i) {\n Market memory market = markets[address(_accountAssets[i])];\n if (market.isListed) {\n assetsIn[len] = _accountAssets[i];\n ++len;\n }\n }\n\n assembly {\n mstore(assetsIn, len)\n }\n\n return assetsIn;\n }\n\n /**\n * @notice Return all of the markets\n * @dev The automatic getter may be used to access an individual market\n * @return The list of market addresses\n */\n function getAllMarkets() external view returns (VToken[] memory) {\n return allMarkets;\n }\n\n /**\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\n * @param vTokenBorrowed The address of the borrowed vToken\n * @param vTokenCollateral The address of the collateral vToken\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\n */\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view returns (uint256, uint256) {\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateCalculateSeizeTokens(\n address(this),\n vTokenBorrowed,\n vTokenCollateral,\n actualRepayAmount\n );\n return (err, seizeTokens);\n }\n\n /**\n * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\n * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\n * @param vTokenCollateral The address of the collateral vToken\n * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\n * @return (errorCode, number of vTokenCollateral tokens to be seized in a liquidation)\n */\n function liquidateVAICalculateSeizeTokens(\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view returns (uint256, uint256) {\n (uint256 err, uint256 seizeTokens) = comptrollerLens.liquidateVAICalculateSeizeTokens(\n address(this),\n vTokenCollateral,\n actualRepayAmount\n );\n return (err, seizeTokens);\n }\n\n /**\n * @notice Returns whether the given account is entered in the given asset\n * @param account The address of the account to check\n * @param vToken The vToken to check\n * @return True if the account is in the asset, otherwise false\n */\n function checkMembership(address account, VToken vToken) external view returns (bool) {\n return markets[address(vToken)].accountMembership[account];\n }\n\n /**\n * @notice Add assets to be included in account liquidity calculation\n * @param vTokens The list of addresses of the vToken markets to be enabled\n * @return Success indicator for whether each corresponding market was entered\n */\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory) {\n uint256 len = vTokens.length;\n\n uint256[] memory results = new uint256[](len);\n for (uint256 i; i < len; ++i) {\n results[i] = uint256(addToMarketInternal(VToken(vTokens[i]), msg.sender));\n }\n\n return results;\n }\n\n /**\n * @notice Unlist a market by setting isListed to false\n * @dev Checks if market actions are paused and borrowCap/supplyCap/CF are set to 0\n * @param market The address of the market (vToken) to unlist\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\n */\n function unlistMarket(address market) external returns (uint256) {\n ensureAllowed(\"unlistMarket(address)\");\n\n Market storage _market = markets[market];\n\n if (!_market.isListed) {\n return fail(Error.MARKET_NOT_LISTED, FailureInfo.UNLIST_MARKET_NOT_LISTED);\n }\n\n require(actionPaused(market, Action.BORROW), \"borrow action is not paused\");\n require(actionPaused(market, Action.MINT), \"mint action is not paused\");\n require(actionPaused(market, Action.REDEEM), \"redeem action is not paused\");\n require(actionPaused(market, Action.REPAY), \"repay action is not paused\");\n require(actionPaused(market, Action.ENTER_MARKET), \"enter market action is not paused\");\n require(actionPaused(market, Action.LIQUIDATE), \"liquidate action is not paused\");\n require(actionPaused(market, Action.SEIZE), \"seize action is not paused\");\n require(actionPaused(market, Action.TRANSFER), \"transfer action is not paused\");\n require(actionPaused(market, Action.EXIT_MARKET), \"exit market action is not paused\");\n\n require(borrowCaps[market] == 0, \"borrow cap is not 0\");\n require(supplyCaps[market] == 0, \"supply cap is not 0\");\n\n require(_market.collateralFactorMantissa == 0, \"collateral factor is not 0\");\n\n _market.isListed = false;\n emit MarketUnlisted(market);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Removes asset from sender's account liquidity calculation\n * @dev Sender must not have an outstanding borrow balance in the asset,\n * or be providing necessary collateral for an outstanding borrow\n * @param vTokenAddress The address of the asset to be removed\n * @return Whether or not the account successfully exited the market\n */\n function exitMarket(address vTokenAddress) external returns (uint256) {\n checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\n\n VToken vToken = VToken(vTokenAddress);\n /* Get sender tokensHeld and amountOwed underlying from the vToken */\n (uint256 oErr, uint256 tokensHeld, uint256 amountOwed, ) = vToken.getAccountSnapshot(msg.sender);\n require(oErr == 0, \"getAccountSnapshot failed\"); // semi-opaque error code\n\n /* Fail if the sender has a borrow balance */\n if (amountOwed != 0) {\n return fail(Error.NONZERO_BORROW_BALANCE, FailureInfo.EXIT_MARKET_BALANCE_OWED);\n }\n\n /* Fail if the sender is not permitted to redeem all of their tokens */\n uint256 allowed = redeemAllowedInternal(vTokenAddress, msg.sender, tokensHeld);\n if (allowed != 0) {\n return failOpaque(Error.REJECTION, FailureInfo.EXIT_MARKET_REJECTION, allowed);\n }\n\n Market storage marketToExit = markets[address(vToken)];\n\n /* Return true if the sender is not already ‘in’ the market */\n if (!marketToExit.accountMembership[msg.sender]) {\n return uint256(Error.NO_ERROR);\n }\n\n /* Set vToken account membership to false */\n delete marketToExit.accountMembership[msg.sender];\n\n /* Delete vToken from the account’s list of assets */\n // In order to delete vToken, copy last item in list to location of item to be removed, reduce length by 1\n VToken[] storage userAssetList = accountAssets[msg.sender];\n uint256 len = userAssetList.length;\n uint256 i;\n for (; i < len; ++i) {\n if (userAssetList[i] == vToken) {\n userAssetList[i] = userAssetList[len - 1];\n userAssetList.length--;\n break;\n }\n }\n\n // We *must* have found the asset in the list or our redundant data structure is broken\n assert(i < len);\n\n emit MarketExited(vToken, msg.sender);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Add the market to the markets mapping and set it as listed\n * @dev Allows a privileged role to add and list markets to the Comptroller\n * @param vToken The address of the market (token) to list\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\n */\n function _supportMarket(VToken vToken) external returns (uint256) {\n ensureAllowed(\"_supportMarket(address)\");\n\n if (markets[address(vToken)].isListed) {\n return fail(Error.MARKET_ALREADY_LISTED, FailureInfo.SUPPORT_MARKET_EXISTS);\n }\n\n vToken.isVToken(); // Sanity check to make sure its really a VToken\n\n // Note that isVenus is not in active use anymore\n Market storage newMarket = markets[address(vToken)];\n newMarket.isListed = true;\n newMarket.isVenus = false;\n newMarket.collateralFactorMantissa = 0;\n\n _addMarketInternal(vToken);\n _initializeMarket(address(vToken));\n\n emit MarketListed(vToken);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account\n * If allowed, the delegate will be able to borrow funds on behalf of the sender\n * Upon a delegated borrow, the delegate will receive the funds, and the borrower\n * will see the debt on their account\n * Upon a delegated redeem, the delegate will receive the redeemed amount and the approver\n * will see a deduction in his vToken balance\n * @param delegate The address to update the rights for\n * @param approved Whether to grant (true) or revoke (false) the borrowing or redeeming rights\n */\n function updateDelegate(address delegate, bool approved) external {\n ensureNonzeroAddress(delegate);\n require(approvedDelegates[msg.sender][delegate] != approved, \"Delegation status unchanged\");\n\n _updateDelegate(msg.sender, delegate, approved);\n }\n\n function _updateDelegate(address approver, address delegate, bool approved) internal {\n approvedDelegates[approver][delegate] = approved;\n emit DelegateUpdated(approver, delegate, approved);\n }\n\n function _addMarketInternal(VToken vToken) internal {\n uint256 allMarketsLength = allMarkets.length;\n for (uint256 i; i < allMarketsLength; ++i) {\n require(allMarkets[i] != vToken, \"already added\");\n }\n allMarkets.push(vToken);\n }\n\n function _initializeMarket(address vToken) internal {\n uint32 blockNumber = getBlockNumberAsUint32();\n\n VenusMarketState storage supplyState = venusSupplyState[vToken];\n VenusMarketState storage borrowState = venusBorrowState[vToken];\n\n /*\n * Update market state indices\n */\n if (supplyState.index == 0) {\n // Initialize supply state index with default value\n supplyState.index = venusInitialIndex;\n }\n\n if (borrowState.index == 0) {\n // Initialize borrow state index with default value\n borrowState.index = venusInitialIndex;\n }\n\n /*\n * Update market state block numbers\n */\n supplyState.block = borrowState.block = blockNumber;\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/PolicyFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { IPolicyFacet } from \"../interfaces/IPolicyFacet.sol\";\n\nimport { XVSRewardsHelper } from \"./XVSRewardsHelper.sol\";\n\n/**\n * @title PolicyFacet\n * @author Venus\n * @dev This facet contains all the hooks used while transferring the assets\n * @notice This facet contract contains all the external pre-hook functions related to vToken\n */\ncontract PolicyFacet is IPolicyFacet, XVSRewardsHelper {\n /// @notice Emitted when a new borrow-side XVS speed is calculated for a market\n event VenusBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /// @notice Emitted when a new supply-side XVS speed is calculated for a market\n event VenusSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\n\n /**\n * @notice Checks if the account should be allowed to mint tokens in the given market\n * @param vToken The market to verify the mint against\n * @param minter The account which would get the minted tokens\n * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens\n * @return 0 if the mint is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256) {\n // Pausing is a very serious situation - we revert to sound the alarms\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.MINT);\n ensureListed(markets[vToken]);\n\n uint256 supplyCap = supplyCaps[vToken];\n require(supplyCap != 0, \"market supply cap is 0\");\n\n uint256 vTokenSupply = VToken(vToken).totalSupply();\n Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\n uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\n require(nextTotalSupply <= supplyCap, \"market supply cap reached\");\n\n // Keep the flywheel moving\n updateVenusSupplyIndex(vToken);\n distributeSupplierVenus(vToken, minter);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset being minted\n * @param minter The address minting the tokens\n * @param actualMintAmount The amount of the underlying asset being minted\n * @param mintTokens The number of tokens being minted\n */\n // solhint-disable-next-line no-unused-vars\n function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(minter, vToken);\n }\n }\n\n /**\n * @notice Checks if the account should be allowed to redeem tokens in the given market\n * @param vToken The market to verify the redeem against\n * @param redeemer The account which would redeem the tokens\n * @param redeemTokens The number of vTokens to exchange for the underlying asset in the market\n * @return 0 if the redeem is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256) {\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.REDEEM);\n\n uint256 allowed = redeemAllowedInternal(vToken, redeemer, redeemTokens);\n if (allowed != uint256(Error.NO_ERROR)) {\n return allowed;\n }\n\n // Keep the flywheel moving\n updateVenusSupplyIndex(vToken);\n distributeSupplierVenus(vToken, redeemer);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset being redeemed\n * @param redeemer The address redeeming the tokens\n * @param redeemAmount The amount of the underlying asset being redeemed\n * @param redeemTokens The number of tokens being redeemed\n */\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {\n require(redeemTokens != 0 || redeemAmount == 0, \"redeemTokens zero\");\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(redeemer, vToken);\n }\n }\n\n /**\n * @notice Checks if the account should be allowed to borrow the underlying asset of the given market\n * @param vToken The market to verify the borrow against\n * @param borrower The account which would borrow the asset\n * @param borrowAmount The amount of underlying the account would borrow\n * @return 0 if the borrow is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256) {\n // Pausing is a very serious situation - we revert to sound the alarms\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.BORROW);\n ensureListed(markets[vToken]);\n\n uint256 borrowCap = borrowCaps[vToken];\n require(borrowCap != 0, \"market borrow cap is 0\");\n\n if (!markets[vToken].accountMembership[borrower]) {\n // only vTokens may call borrowAllowed if borrower not in market\n require(msg.sender == vToken, \"sender must be vToken\");\n\n // attempt to add borrower to the market\n Error err = addToMarketInternal(VToken(vToken), borrower);\n if (err != Error.NO_ERROR) {\n return uint256(err);\n }\n }\n\n if (oracle.getUnderlyingPrice(VToken(vToken)) == 0) {\n return uint256(Error.PRICE_ERROR);\n }\n\n uint256 nextTotalBorrows = add_(VToken(vToken).totalBorrows(), borrowAmount);\n require(nextTotalBorrows <= borrowCap, \"market borrow cap reached\");\n\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\n borrower,\n VToken(vToken),\n 0,\n borrowAmount\n );\n if (err != Error.NO_ERROR) {\n return uint256(err);\n }\n if (shortfall != 0) {\n return uint256(Error.INSUFFICIENT_LIQUIDITY);\n }\n\n // Keep the flywheel moving\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n updateVenusBorrowIndex(vToken, borrowIndex);\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset whose underlying is being borrowed\n * @param borrower The address borrowing the underlying\n * @param borrowAmount The amount of the underlying asset requested to borrow\n */\n // solhint-disable-next-line no-unused-vars\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(borrower, vToken);\n }\n }\n\n /**\n * @notice Checks if the account should be allowed to repay a borrow in the given market\n * @param vToken The market to verify the repay against\n * @param payer The account which would repay the asset\n * @param borrower The account which borrowed the asset\n * @param repayAmount The amount of the underlying asset the account would repay\n * @return 0 if the repay is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function repayBorrowAllowed(\n address vToken,\n address payer, // solhint-disable-line no-unused-vars\n address borrower,\n uint256 repayAmount // solhint-disable-line no-unused-vars\n ) external returns (uint256) {\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.REPAY);\n ensureListed(markets[vToken]);\n\n // Keep the flywheel moving\n Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\n updateVenusBorrowIndex(vToken, borrowIndex);\n distributeBorrowerVenus(vToken, borrower, borrowIndex);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset being repaid\n * @param payer The address repaying the borrow\n * @param borrower The address of the borrower\n * @param actualRepayAmount The amount of underlying being repaid\n */\n function repayBorrowVerify(\n address vToken,\n address payer, // solhint-disable-line no-unused-vars\n address borrower,\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\n uint256 borrowerIndex // solhint-disable-line no-unused-vars\n ) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(borrower, vToken);\n }\n }\n\n /**\n * @notice Checks if the liquidation should be allowed to occur\n * @param vTokenBorrowed Asset which was borrowed by the borrower\n * @param vTokenCollateral Asset which was used as collateral and will be seized\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @param repayAmount The amount of underlying being repaid\n */\n function liquidateBorrowAllowed(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint256 repayAmount\n ) external view returns (uint256) {\n checkProtocolPauseState();\n\n // if we want to pause liquidating to vTokenCollateral, we should pause seizing\n checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\n\n if (liquidatorContract != address(0) && liquidator != liquidatorContract) {\n return uint256(Error.UNAUTHORIZED);\n }\n\n ensureListed(markets[vTokenCollateral]);\n\n uint256 borrowBalance;\n if (address(vTokenBorrowed) != address(vaiController)) {\n ensureListed(markets[vTokenBorrowed]);\n borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\n } else {\n borrowBalance = vaiController.getVAIRepayAmount(borrower);\n }\n\n if (isForcedLiquidationEnabled[vTokenBorrowed] || isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed]) {\n if (repayAmount > borrowBalance) {\n return uint(Error.TOO_MUCH_REPAY);\n }\n return uint(Error.NO_ERROR);\n }\n\n /* The borrower must have shortfall in order to be liquidatable */\n (Error err, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(borrower, VToken(address(0)), 0, 0);\n if (err != Error.NO_ERROR) {\n return uint256(err);\n }\n if (shortfall == 0) {\n return uint256(Error.INSUFFICIENT_SHORTFALL);\n }\n\n // The liquidator may not repay more than what is allowed by the closeFactor\n //-- maxClose = multipy of closeFactorMantissa and borrowBalance\n if (repayAmount > mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance)) {\n return uint256(Error.TOO_MUCH_REPAY);\n }\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vTokenBorrowed Asset which was borrowed by the borrower\n * @param vTokenCollateral Asset which was used as collateral and will be seized\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @param actualRepayAmount The amount of underlying being repaid\n * @param seizeTokens The amount of collateral token that will be seized\n */\n function liquidateBorrowVerify(\n address vTokenBorrowed,\n address vTokenCollateral, // solhint-disable-line no-unused-vars\n address liquidator,\n address borrower,\n uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\n uint256 seizeTokens // solhint-disable-line no-unused-vars\n ) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(borrower, vTokenBorrowed);\n prime.accrueInterestAndUpdateScore(liquidator, vTokenBorrowed);\n }\n }\n\n /**\n * @notice Checks if the seizing of assets should be allowed to occur\n * @param vTokenCollateral Asset which was used as collateral and will be seized\n * @param vTokenBorrowed Asset which was borrowed by the borrower\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @param seizeTokens The number of collateral tokens to seize\n */\n function seizeAllowed(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint256 seizeTokens // solhint-disable-line no-unused-vars\n ) external returns (uint256) {\n // Pausing is a very serious situation - we revert to sound the alarms\n checkProtocolPauseState();\n checkActionPauseState(vTokenCollateral, Action.SEIZE);\n\n Market storage market = markets[vTokenCollateral];\n\n // We've added VAIController as a borrowed token list check for seize\n ensureListed(market);\n\n if (!market.accountMembership[borrower]) {\n return uint256(Error.MARKET_NOT_COLLATERAL);\n }\n\n if (address(vTokenBorrowed) != address(vaiController)) {\n ensureListed(markets[vTokenBorrowed]);\n }\n\n if (VToken(vTokenCollateral).comptroller() != VToken(vTokenBorrowed).comptroller()) {\n return uint256(Error.COMPTROLLER_MISMATCH);\n }\n\n // Keep the flywheel moving\n updateVenusSupplyIndex(vTokenCollateral);\n distributeSupplierVenus(vTokenCollateral, borrower);\n distributeSupplierVenus(vTokenCollateral, liquidator);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vTokenCollateral Asset which was used as collateral and will be seized\n * @param vTokenBorrowed Asset which was borrowed by the borrower\n * @param liquidator The address repaying the borrow and seizing the collateral\n * @param borrower The address of the borrower\n * @param seizeTokens The number of collateral tokens to seize\n */\n function seizeVerify(\n address vTokenCollateral,\n address vTokenBorrowed, // solhint-disable-line no-unused-vars\n address liquidator,\n address borrower,\n uint256 seizeTokens // solhint-disable-line no-unused-vars\n ) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(borrower, vTokenCollateral);\n prime.accrueInterestAndUpdateScore(liquidator, vTokenCollateral);\n }\n }\n\n /**\n * @notice Checks if the account should be allowed to transfer tokens in the given market\n * @param vToken The market to verify the transfer against\n * @param src The account which sources the tokens\n * @param dst The account which receives the tokens\n * @param transferTokens The number of vTokens to transfer\n * @return 0 if the transfer is allowed, otherwise a semi-opaque error code (See ErrorReporter.sol)\n */\n function transferAllowed(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external returns (uint256) {\n // Pausing is a very serious situation - we revert to sound the alarms\n checkProtocolPauseState();\n checkActionPauseState(vToken, Action.TRANSFER);\n\n // Currently the only consideration is whether or not\n // the src is allowed to redeem this many tokens\n uint256 allowed = redeemAllowedInternal(vToken, src, transferTokens);\n if (allowed != uint256(Error.NO_ERROR)) {\n return allowed;\n }\n\n // Keep the flywheel moving\n updateVenusSupplyIndex(vToken);\n distributeSupplierVenus(vToken, src);\n distributeSupplierVenus(vToken, dst);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\n * @param vToken Asset being transferred\n * @param src The account which sources the tokens\n * @param dst The account which receives the tokens\n * @param transferTokens The number of vTokens to transfer\n */\n // solhint-disable-next-line no-unused-vars\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external {\n if (address(prime) != address(0)) {\n prime.accrueInterestAndUpdateScore(src, vToken);\n prime.accrueInterestAndUpdateScore(dst, vToken);\n }\n }\n\n /**\n * @notice Determine the current account liquidity wrt collateral requirements\n * @return (possible error code (semi-opaque),\n account liquidity in excess of collateral requirements,\n * account shortfall below collateral requirements)\n */\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256) {\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\n account,\n VToken(address(0)),\n 0,\n 0\n );\n\n return (uint256(err), liquidity, shortfall);\n }\n\n /**\n * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\n * @param vTokenModify The market to hypothetically redeem/borrow in\n * @param account The account to determine liquidity for\n * @param redeemTokens The number of tokens to hypothetically redeem\n * @param borrowAmount The amount of underlying to hypothetically borrow\n * @return (possible error code (semi-opaque),\n hypothetical account liquidity in excess of collateral requirements,\n * hypothetical account shortfall below collateral requirements)\n */\n function getHypotheticalAccountLiquidity(\n address account,\n address vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n ) external view returns (uint256, uint256, uint256) {\n (Error err, uint256 liquidity, uint256 shortfall) = getHypotheticalAccountLiquidityInternal(\n account,\n VToken(vTokenModify),\n redeemTokens,\n borrowAmount\n );\n return (uint256(err), liquidity, shortfall);\n }\n\n // setter functionality\n /**\n * @notice Set XVS speed for a single market\n * @dev Allows the contract admin to set XVS speed for a market\n * @param vTokens The market whose XVS speed to update\n * @param supplySpeeds New XVS speed for supply\n * @param borrowSpeeds New XVS speed for borrow\n */\n function _setVenusSpeeds(\n VToken[] calldata vTokens,\n uint256[] calldata supplySpeeds,\n uint256[] calldata borrowSpeeds\n ) external {\n ensureAdmin();\n\n uint256 numTokens = vTokens.length;\n require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \"invalid input\");\n\n for (uint256 i; i < numTokens; ++i) {\n ensureNonzeroAddress(address(vTokens[i]));\n setVenusSpeedInternal(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\n }\n }\n\n function setVenusSpeedInternal(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal {\n ensureListed(markets[address(vToken)]);\n\n if (venusSupplySpeeds[address(vToken)] != supplySpeed) {\n // Supply speed updated so let's update supply state to ensure that\n // 1. XVS accrued properly for the old speed, and\n // 2. XVS accrued at the new speed starts after this block.\n\n updateVenusSupplyIndex(address(vToken));\n // Update speed and emit event\n venusSupplySpeeds[address(vToken)] = supplySpeed;\n emit VenusSupplySpeedUpdated(vToken, supplySpeed);\n }\n\n if (venusBorrowSpeeds[address(vToken)] != borrowSpeed) {\n // Borrow speed updated so let's update borrow state to ensure that\n // 1. XVS accrued properly for the old speed, and\n // 2. XVS accrued at the new speed starts after this block.\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n updateVenusBorrowIndex(address(vToken), borrowIndex);\n\n // Update speed and emit event\n venusBorrowSpeeds[address(vToken)] = borrowSpeed;\n emit VenusBorrowSpeedUpdated(vToken, borrowSpeed);\n }\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/RewardFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { IRewardFacet } from \"../interfaces/IRewardFacet.sol\";\nimport { XVSRewardsHelper } from \"./XVSRewardsHelper.sol\";\nimport { SafeBEP20, IBEP20 } from \"../../../Utils/SafeBEP20.sol\";\nimport { VBep20Interface } from \"../../../Tokens/VTokens/VTokenInterfaces.sol\";\n\n/**\n * @title RewardFacet\n * @author Venus\n * @dev This facet contains all the methods related to the reward functionality\n * @notice This facet contract provides the external functions related to all claims and rewards of the protocol\n */\ncontract RewardFacet is IRewardFacet, XVSRewardsHelper {\n /// @notice Emitted when Venus is granted by admin\n event VenusGranted(address indexed recipient, uint256 amount);\n\n /// @notice Emitted when XVS are seized for the holder\n event VenusSeized(address indexed holder, uint256 amount);\n\n using SafeBEP20 for IBEP20;\n\n /**\n * @notice Claim all the xvs accrued by holder in all markets and VAI\n * @param holder The address to claim XVS for\n */\n function claimVenus(address holder) public {\n return claimVenus(holder, allMarkets);\n }\n\n /**\n * @notice Claim all the xvs accrued by holder in the specified markets\n * @param holder The address to claim XVS for\n * @param vTokens The list of markets to claim XVS in\n */\n function claimVenus(address holder, VToken[] memory vTokens) public {\n address[] memory holders = new address[](1);\n holders[0] = holder;\n claimVenus(holders, vTokens, true, true);\n }\n\n /**\n * @notice Claim all xvs accrued by the holders\n * @param holders The addresses to claim XVS for\n * @param vTokens The list of markets to claim XVS in\n * @param borrowers Whether or not to claim XVS earned by borrowing\n * @param suppliers Whether or not to claim XVS earned by supplying\n */\n function claimVenus(address[] memory holders, VToken[] memory vTokens, bool borrowers, bool suppliers) public {\n claimVenus(holders, vTokens, borrowers, suppliers, false);\n }\n\n /**\n * @notice Claim all the xvs accrued by holder in all markets, a shorthand for `claimVenus` with collateral set to `true`\n * @param holder The address to claim XVS for\n */\n function claimVenusAsCollateral(address holder) external {\n address[] memory holders = new address[](1);\n holders[0] = holder;\n claimVenus(holders, allMarkets, true, true, true);\n }\n\n /**\n * @notice Transfer XVS to the user with user's shortfall considered\n * @dev Note: If there is not enough XVS, we do not perform the transfer all\n * @param user The address of the user to transfer XVS to\n * @param amount The amount of XVS to (possibly) transfer\n * @param shortfall The shortfall of the user\n * @param collateral Whether or not we will use user's venus reward as collateral to pay off the debt\n * @return The amount of XVS which was NOT transferred to the user\n */\n function grantXVSInternal(\n address user,\n uint256 amount,\n uint256 shortfall,\n bool collateral\n ) internal returns (uint256) {\n // If the user is blacklisted, they can't get XVS rewards\n require(\n user != 0xEF044206Db68E40520BfA82D45419d498b4bc7Bf &&\n user != 0x7589dD3355DAE848FDbF75044A3495351655cB1A &&\n user != 0x33df7a7F6D44307E1e5F3B15975b47515e5524c0 &&\n user != 0x24e77E5b74B30b026E9996e4bc3329c881e24968,\n \"Blacklisted\"\n );\n\n IBEP20 xvs_ = IBEP20(xvs);\n\n if (amount == 0 || amount > xvs_.balanceOf(address(this))) {\n return amount;\n }\n\n if (shortfall == 0) {\n xvs_.safeTransfer(user, amount);\n return 0;\n }\n // If user's bankrupt and doesn't use pending xvs as collateral, don't grant\n // anything, otherwise, we will transfer the pending xvs as collateral to\n // vXVS token and mint vXVS for the user\n //\n // If mintBehalf failed, don't grant any xvs\n require(collateral, \"bankrupt\");\n\n address xvsVToken_ = xvsVToken;\n\n xvs_.safeApprove(xvsVToken_, 0);\n xvs_.safeApprove(xvsVToken_, amount);\n require(VBep20Interface(xvsVToken_).mintBehalf(user, amount) == uint256(Error.NO_ERROR), \"mint behalf error\");\n\n // set venusAccrued[user] to 0\n return 0;\n }\n\n /*** Venus Distribution Admin ***/\n\n /**\n * @notice Transfer XVS to the recipient\n * @dev Allows the contract admin to transfer XVS to any recipient based on the recipient's shortfall\n * Note: If there is not enough XVS, we do not perform the transfer all\n * @param recipient The address of the recipient to transfer XVS to\n * @param amount The amount of XVS to (possibly) transfer\n */\n function _grantXVS(address recipient, uint256 amount) external {\n ensureAdmin();\n uint256 amountLeft = grantXVSInternal(recipient, amount, 0, false);\n require(amountLeft == 0, \"no xvs\");\n emit VenusGranted(recipient, amount);\n }\n\n /**\n * @dev Seize XVS tokens from the specified holders and transfer to recipient\n * @notice Seize XVS rewards allocated to holders\n * @param holders Addresses of the XVS holders\n * @param recipient Address of the XVS token recipient\n * @return The total amount of XVS tokens seized and transferred to recipient\n */\n function seizeVenus(address[] calldata holders, address recipient) external returns (uint256) {\n ensureAllowed(\"seizeVenus(address[],address)\");\n\n uint256 holdersLength = holders.length;\n uint256 totalHoldings;\n\n updateAndDistributeRewardsInternal(holders, allMarkets, true, true);\n for (uint256 j; j < holdersLength; ++j) {\n address holder = holders[j];\n uint256 userHolding = venusAccrued[holder];\n\n if (userHolding != 0) {\n totalHoldings += userHolding;\n delete venusAccrued[holder];\n }\n\n emit VenusSeized(holder, userHolding);\n }\n\n if (totalHoldings != 0) {\n IBEP20(xvs).safeTransfer(recipient, totalHoldings);\n emit VenusGranted(recipient, totalHoldings);\n }\n\n return totalHoldings;\n }\n\n /**\n * @notice Claim all xvs accrued by the holders\n * @param holders The addresses to claim XVS for\n * @param vTokens The list of markets to claim XVS in\n * @param borrowers Whether or not to claim XVS earned by borrowing\n * @param suppliers Whether or not to claim XVS earned by supplying\n * @param collateral Whether or not to use XVS earned as collateral, only takes effect when the holder has a shortfall\n */\n function claimVenus(\n address[] memory holders,\n VToken[] memory vTokens,\n bool borrowers,\n bool suppliers,\n bool collateral\n ) public {\n uint256 holdersLength = holders.length;\n\n updateAndDistributeRewardsInternal(holders, vTokens, borrowers, suppliers);\n for (uint256 j; j < holdersLength; ++j) {\n address holder = holders[j];\n\n // If there is a positive shortfall, the XVS reward is accrued,\n // but won't be granted to this holder\n (, , uint256 shortfall) = getHypotheticalAccountLiquidityInternal(holder, VToken(address(0)), 0, 0);\n\n uint256 value = venusAccrued[holder];\n delete venusAccrued[holder];\n\n uint256 returnAmount = grantXVSInternal(holder, value, shortfall, collateral);\n\n // returnAmount can only be positive if balance of xvsAddress is less than grant amount(venusAccrued[holder])\n if (returnAmount != 0) {\n venusAccrued[holder] = returnAmount;\n }\n }\n }\n\n /**\n * @notice Update and distribute tokens\n * @param holders The addresses to claim XVS for\n * @param vTokens The list of markets to claim XVS in\n * @param borrowers Whether or not to claim XVS earned by borrowing\n * @param suppliers Whether or not to claim XVS earned by supplying\n */\n function updateAndDistributeRewardsInternal(\n address[] memory holders,\n VToken[] memory vTokens,\n bool borrowers,\n bool suppliers\n ) internal {\n uint256 j;\n uint256 holdersLength = holders.length;\n uint256 vTokensLength = vTokens.length;\n\n for (uint256 i; i < vTokensLength; ++i) {\n VToken vToken = vTokens[i];\n ensureListed(markets[address(vToken)]);\n if (borrowers) {\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n updateVenusBorrowIndex(address(vToken), borrowIndex);\n for (j = 0; j < holdersLength; ++j) {\n distributeBorrowerVenus(address(vToken), holders[j], borrowIndex);\n }\n }\n\n if (suppliers) {\n updateVenusSupplyIndex(address(vToken));\n for (j = 0; j < holdersLength; ++j) {\n distributeSupplierVenus(address(vToken), holders[j]);\n }\n }\n }\n }\n\n /**\n * @notice Returns the XVS vToken address\n * @return The address of XVS vToken\n */\n function getXVSVTokenAddress() external view returns (address) {\n return xvsVToken;\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/SetterFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { ISetterFacet } from \"../interfaces/ISetterFacet.sol\";\nimport { PriceOracle } from \"../../../Oracle/PriceOracle.sol\";\nimport { ComptrollerLensInterface } from \"../../ComptrollerLensInterface.sol\";\nimport { VAIControllerInterface } from \"../../../Tokens/VAI/VAIControllerInterface.sol\";\nimport { FacetBase } from \"./FacetBase.sol\";\nimport { IPrime } from \"../../../Tokens/Prime/IPrime.sol\";\n\n/**\n * @title SetterFacet\n * @author Venus\n * @dev This facet contains all the setters for the states\n * @notice This facet contract contains all the configurational setter functions\n */\ncontract SetterFacet is ISetterFacet, FacetBase {\n /// @notice Emitted when close factor is changed by admin\n event NewCloseFactor(uint256 oldCloseFactorMantissa, uint256 newCloseFactorMantissa);\n\n /// @notice Emitted when a collateral factor is changed by admin\n event NewCollateralFactor(\n VToken indexed vToken,\n uint256 oldCollateralFactorMantissa,\n uint256 newCollateralFactorMantissa\n );\n\n /// @notice Emitted when liquidation incentive is changed by admin\n event NewLiquidationIncentive(uint256 oldLiquidationIncentiveMantissa, uint256 newLiquidationIncentiveMantissa);\n\n /// @notice Emitted when price oracle is changed\n event NewPriceOracle(PriceOracle oldPriceOracle, PriceOracle newPriceOracle);\n\n /// @notice Emitted when borrow cap for a vToken is changed\n event NewBorrowCap(VToken indexed vToken, uint256 newBorrowCap);\n\n /// @notice Emitted when VAIController is changed\n event NewVAIController(VAIControllerInterface oldVAIController, VAIControllerInterface newVAIController);\n\n /// @notice Emitted when VAI mint rate is changed by admin\n event NewVAIMintRate(uint256 oldVAIMintRate, uint256 newVAIMintRate);\n\n /// @notice Emitted when protocol state is changed by admin\n event ActionProtocolPaused(bool state);\n\n /// @notice Emitted when treasury guardian is changed\n event NewTreasuryGuardian(address oldTreasuryGuardian, address newTreasuryGuardian);\n\n /// @notice Emitted when treasury address is changed\n event NewTreasuryAddress(address oldTreasuryAddress, address newTreasuryAddress);\n\n /// @notice Emitted when treasury percent is changed\n event NewTreasuryPercent(uint256 oldTreasuryPercent, uint256 newTreasuryPercent);\n\n /// @notice Emitted when liquidator adress is changed\n event NewLiquidatorContract(address oldLiquidatorContract, address newLiquidatorContract);\n\n /// @notice Emitted when ComptrollerLens address is changed\n event NewComptrollerLens(address oldComptrollerLens, address newComptrollerLens);\n\n /// @notice Emitted when supply cap for a vToken is changed\n event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap);\n\n /// @notice Emitted when access control address is changed by admin\n event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress);\n\n /// @notice Emitted when pause guardian is changed\n event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian);\n\n /// @notice Emitted when an action is paused on a market\n event ActionPausedMarket(VToken indexed vToken, Action indexed action, bool pauseState);\n\n /// @notice Emitted when VAI Vault info is changed\n event NewVAIVaultInfo(address indexed vault_, uint256 releaseStartBlock_, uint256 releaseInterval_);\n\n /// @notice Emitted when Venus VAI Vault rate is changed\n event NewVenusVAIVaultRate(uint256 oldVenusVAIVaultRate, uint256 newVenusVAIVaultRate);\n\n /// @notice Emitted when prime token contract address is changed\n event NewPrimeToken(IPrime oldPrimeToken, IPrime newPrimeToken);\n\n /// @notice Emitted when forced liquidation is enabled or disabled for all users in a market\n event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);\n\n /// @notice Emitted when forced liquidation is enabled or disabled for a user borrowing in a market\n event IsForcedLiquidationEnabledForUserUpdated(address indexed borrower, address indexed vToken, bool enable);\n\n /// @notice Emitted when XVS token address is changed\n event NewXVSToken(address indexed oldXVS, address indexed newXVS);\n\n /// @notice Emitted when XVS vToken address is changed\n event NewXVSVToken(address indexed oldXVSVToken, address indexed newXVSVToken);\n\n /**\n * @notice Compare two addresses to ensure they are different\n * @param oldAddress The original address to compare\n * @param newAddress The new address to compare\n */\n modifier compareAddress(address oldAddress, address newAddress) {\n require(oldAddress != newAddress, \"old address is same as new address\");\n _;\n }\n\n /**\n * @notice Compare two values to ensure they are different\n * @param oldValue The original value to compare\n * @param newValue The new value to compare\n */\n modifier compareValue(uint256 oldValue, uint256 newValue) {\n require(oldValue != newValue, \"old value is same as new value\");\n _;\n }\n\n /**\n * @notice Sets a new price oracle for the comptroller\n * @dev Allows the contract admin to set a new price oracle used by the Comptroller\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPriceOracle(\n PriceOracle newOracle\n ) external compareAddress(address(oracle), address(newOracle)) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n ensureNonzeroAddress(address(newOracle));\n\n // Track the old oracle for the comptroller\n PriceOracle oldOracle = oracle;\n\n // Set comptroller's oracle to newOracle\n oracle = newOracle;\n\n // Emit NewPriceOracle(oldOracle, newOracle)\n emit NewPriceOracle(oldOracle, newOracle);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets the closeFactor used when liquidating borrows\n * @dev Allows the contract admin to set the closeFactor used to liquidate borrows\n * @param newCloseFactorMantissa New close factor, scaled by 1e18\n * @return uint256 0=success, otherwise will revert\n */\n function _setCloseFactor(\n uint256 newCloseFactorMantissa\n ) external compareValue(closeFactorMantissa, newCloseFactorMantissa) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n\n Exp memory newCloseFactorExp = Exp({ mantissa: newCloseFactorMantissa });\n\n //-- Check close factor <= 0.9\n Exp memory highLimit = Exp({ mantissa: closeFactorMaxMantissa });\n //-- Check close factor >= 0.05\n Exp memory lowLimit = Exp({ mantissa: closeFactorMinMantissa });\n\n if (lessThanExp(highLimit, newCloseFactorExp) || greaterThanExp(lowLimit, newCloseFactorExp)) {\n return fail(Error.INVALID_CLOSE_FACTOR, FailureInfo.SET_CLOSE_FACTOR_VALIDATION);\n }\n\n uint256 oldCloseFactorMantissa = closeFactorMantissa;\n closeFactorMantissa = newCloseFactorMantissa;\n emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Allows the contract admin to set the address of access control of this contract\n * @param newAccessControlAddress New address for the access control\n * @return uint256 0=success, otherwise will revert\n */\n function _setAccessControl(\n address newAccessControlAddress\n ) external compareAddress(accessControl, newAccessControlAddress) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n ensureNonzeroAddress(newAccessControlAddress);\n\n address oldAccessControlAddress = accessControl;\n\n accessControl = newAccessControlAddress;\n emit NewAccessControl(oldAccessControlAddress, newAccessControlAddress);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets the collateralFactor for a market\n * @dev Allows a privileged role to set the collateralFactorMantissa\n * @param vToken The market to set the factor on\n * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\n */\n function _setCollateralFactor(\n VToken vToken,\n uint256 newCollateralFactorMantissa\n )\n external\n compareValue(markets[address(vToken)].collateralFactorMantissa, newCollateralFactorMantissa)\n returns (uint256)\n {\n // Check caller is allowed by access control manager\n ensureAllowed(\"_setCollateralFactor(address,uint256)\");\n ensureNonzeroAddress(address(vToken));\n\n // Verify market is listed\n Market storage market = markets[address(vToken)];\n ensureListed(market);\n\n Exp memory newCollateralFactorExp = Exp({ mantissa: newCollateralFactorMantissa });\n\n //-- Check collateral factor <= 0.9\n Exp memory highLimit = Exp({ mantissa: collateralFactorMaxMantissa });\n if (lessThanExp(highLimit, newCollateralFactorExp)) {\n return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION);\n }\n\n // If collateral factor != 0, fail if price == 0\n if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(vToken) == 0) {\n return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE);\n }\n\n // Set market's collateral factor to new collateral factor, remember old value\n uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\n market.collateralFactorMantissa = newCollateralFactorMantissa;\n\n // Emit event with asset, old collateral factor, and new collateral factor\n emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets liquidationIncentive\n * @dev Allows a privileged role to set the liquidationIncentiveMantissa\n * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\n * @return uint256 0=success, otherwise a failure. (See ErrorReporter for details)\n */\n function _setLiquidationIncentive(\n uint256 newLiquidationIncentiveMantissa\n ) external compareValue(liquidationIncentiveMantissa, newLiquidationIncentiveMantissa) returns (uint256) {\n ensureAllowed(\"_setLiquidationIncentive(uint256)\");\n\n require(newLiquidationIncentiveMantissa >= 1e18, \"incentive < 1e18\");\n\n // Save current value for use in log\n uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\n // Set liquidation incentive to new incentive\n liquidationIncentiveMantissa = newLiquidationIncentiveMantissa;\n\n // Emit event with old incentive, new incentive\n emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Update the address of the liquidator contract\n * @dev Allows the contract admin to update the address of liquidator contract\n * @param newLiquidatorContract_ The new address of the liquidator contract\n */\n function _setLiquidatorContract(\n address newLiquidatorContract_\n ) external compareAddress(liquidatorContract, newLiquidatorContract_) {\n // Check caller is admin\n ensureAdmin();\n ensureNonzeroAddress(newLiquidatorContract_);\n address oldLiquidatorContract = liquidatorContract;\n liquidatorContract = newLiquidatorContract_;\n emit NewLiquidatorContract(oldLiquidatorContract, newLiquidatorContract_);\n }\n\n /**\n * @notice Admin function to change the Pause Guardian\n * @dev Allows the contract admin to change the Pause Guardian\n * @param newPauseGuardian The address of the new Pause Guardian\n * @return uint256 0=success, otherwise a failure. (See enum Error for details)\n */\n function _setPauseGuardian(\n address newPauseGuardian\n ) external compareAddress(pauseGuardian, newPauseGuardian) returns (uint256) {\n ensureAdmin();\n ensureNonzeroAddress(newPauseGuardian);\n\n // Save current value for inclusion in log\n address oldPauseGuardian = pauseGuardian;\n // Store pauseGuardian with value newPauseGuardian\n pauseGuardian = newPauseGuardian;\n\n // Emit NewPauseGuardian(OldPauseGuardian, NewPauseGuardian)\n emit NewPauseGuardian(oldPauseGuardian, newPauseGuardian);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the given borrow caps for the given vToken market Borrowing that brings total borrows to or above borrow cap will revert\n * @dev Allows a privileged role to set the borrowing cap for a vToken market. A borrow cap of 0 corresponds to Borrow not allowed\n * @param vTokens The addresses of the markets (tokens) to change the borrow caps for\n * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of 0 corresponds to Borrow not allowed\n */\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\n ensureAllowed(\"_setMarketBorrowCaps(address[],uint256[])\");\n\n uint256 numMarkets = vTokens.length;\n uint256 numBorrowCaps = newBorrowCaps.length;\n\n require(numMarkets != 0 && numMarkets == numBorrowCaps, \"invalid input\");\n\n for (uint256 i; i < numMarkets; ++i) {\n borrowCaps[address(vTokens[i])] = newBorrowCaps[i];\n emit NewBorrowCap(vTokens[i], newBorrowCaps[i]);\n }\n }\n\n /**\n * @notice Set the given supply caps for the given vToken market Supply that brings total Supply to or above supply cap will revert\n * @dev Allows a privileged role to set the supply cap for a vToken. A supply cap of 0 corresponds to Minting NotAllowed\n * @param vTokens The addresses of the markets (tokens) to change the supply caps for\n * @param newSupplyCaps The new supply cap values in underlying to be set. A value of 0 corresponds to Minting NotAllowed\n */\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\n ensureAllowed(\"_setMarketSupplyCaps(address[],uint256[])\");\n\n uint256 numMarkets = vTokens.length;\n uint256 numSupplyCaps = newSupplyCaps.length;\n\n require(numMarkets != 0 && numMarkets == numSupplyCaps, \"invalid input\");\n\n for (uint256 i; i < numMarkets; ++i) {\n supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\n emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\n }\n }\n\n /**\n * @notice Set whole protocol pause/unpause state\n * @dev Allows a privileged role to pause/unpause protocol\n * @param state The new state (true=paused, false=unpaused)\n * @return bool The updated state of the protocol\n */\n function _setProtocolPaused(bool state) external returns (bool) {\n ensureAllowed(\"_setProtocolPaused(bool)\");\n\n protocolPaused = state;\n emit ActionProtocolPaused(state);\n return state;\n }\n\n /**\n * @notice Pause/unpause certain actions\n * @dev Allows a privileged role to pause/unpause the protocol action state\n * @param markets_ Markets to pause/unpause the actions on\n * @param actions_ List of action ids to pause/unpause\n * @param paused_ The new paused state (true=paused, false=unpaused)\n */\n function _setActionsPaused(address[] calldata markets_, Action[] calldata actions_, bool paused_) external {\n ensureAllowed(\"_setActionsPaused(address[],uint8[],bool)\");\n\n uint256 numMarkets = markets_.length;\n uint256 numActions = actions_.length;\n for (uint256 marketIdx; marketIdx < numMarkets; ++marketIdx) {\n for (uint256 actionIdx; actionIdx < numActions; ++actionIdx) {\n setActionPausedInternal(markets_[marketIdx], actions_[actionIdx], paused_);\n }\n }\n }\n\n /**\n * @dev Pause/unpause an action on a market\n * @param market Market to pause/unpause the action on\n * @param action Action id to pause/unpause\n * @param paused The new paused state (true=paused, false=unpaused)\n */\n function setActionPausedInternal(address market, Action action, bool paused) internal {\n ensureListed(markets[market]);\n _actionPaused[market][uint256(action)] = paused;\n emit ActionPausedMarket(VToken(market), action, paused);\n }\n\n /**\n * @notice Sets a new VAI controller\n * @dev Admin function to set a new VAI controller\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setVAIController(\n VAIControllerInterface vaiController_\n ) external compareAddress(address(vaiController), address(vaiController_)) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n ensureNonzeroAddress(address(vaiController_));\n\n VAIControllerInterface oldVaiController = vaiController;\n vaiController = vaiController_;\n emit NewVAIController(oldVaiController, vaiController_);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the VAI mint rate\n * @param newVAIMintRate The new VAI mint rate to be set\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setVAIMintRate(\n uint256 newVAIMintRate\n ) external compareValue(vaiMintRate, newVAIMintRate) returns (uint256) {\n // Check caller is admin\n ensureAdmin();\n uint256 oldVAIMintRate = vaiMintRate;\n vaiMintRate = newVAIMintRate;\n emit NewVAIMintRate(oldVAIMintRate, newVAIMintRate);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the minted VAI amount of the `owner`\n * @param owner The address of the account to set\n * @param amount The amount of VAI to set to the account\n * @return The number of minted VAI by `owner`\n */\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256) {\n checkProtocolPauseState();\n\n // Pausing is a very serious situation - we revert to sound the alarms\n require(!mintVAIGuardianPaused && !repayVAIGuardianPaused, \"VAI is paused\");\n // Check caller is vaiController\n if (msg.sender != address(vaiController)) {\n return fail(Error.REJECTION, FailureInfo.SET_MINTED_VAI_REJECTION);\n }\n mintedVAIs[owner] = amount;\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the treasury data.\n * @param newTreasuryGuardian The new address of the treasury guardian to be set\n * @param newTreasuryAddress The new address of the treasury to be set\n * @param newTreasuryPercent The new treasury percent to be set\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setTreasuryData(\n address newTreasuryGuardian,\n address newTreasuryAddress,\n uint256 newTreasuryPercent\n ) external returns (uint256) {\n // Check caller is admin\n ensureAdminOr(treasuryGuardian);\n\n require(newTreasuryPercent < 1e18, \"percent >= 100%\");\n ensureNonzeroAddress(newTreasuryGuardian);\n ensureNonzeroAddress(newTreasuryAddress);\n\n address oldTreasuryGuardian = treasuryGuardian;\n address oldTreasuryAddress = treasuryAddress;\n uint256 oldTreasuryPercent = treasuryPercent;\n\n treasuryGuardian = newTreasuryGuardian;\n treasuryAddress = newTreasuryAddress;\n treasuryPercent = newTreasuryPercent;\n\n emit NewTreasuryGuardian(oldTreasuryGuardian, newTreasuryGuardian);\n emit NewTreasuryAddress(oldTreasuryAddress, newTreasuryAddress);\n emit NewTreasuryPercent(oldTreasuryPercent, newTreasuryPercent);\n\n return uint256(Error.NO_ERROR);\n }\n\n /*** Venus Distribution ***/\n\n /**\n * @dev Set ComptrollerLens contract address\n * @param comptrollerLens_ The new ComptrollerLens contract address to be set\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setComptrollerLens(\n ComptrollerLensInterface comptrollerLens_\n ) external compareAddress(address(comptrollerLens), address(comptrollerLens_)) returns (uint256) {\n ensureAdmin();\n ensureNonzeroAddress(address(comptrollerLens_));\n address oldComptrollerLens = address(comptrollerLens);\n comptrollerLens = comptrollerLens_;\n emit NewComptrollerLens(oldComptrollerLens, address(comptrollerLens));\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the amount of XVS distributed per block to VAI Vault\n * @param venusVAIVaultRate_ The amount of XVS wei per block to distribute to VAI Vault\n */\n function _setVenusVAIVaultRate(\n uint256 venusVAIVaultRate_\n ) external compareValue(venusVAIVaultRate, venusVAIVaultRate_) {\n ensureAdmin();\n if (vaiVaultAddress != address(0)) {\n releaseToVault();\n }\n uint256 oldVenusVAIVaultRate = venusVAIVaultRate;\n venusVAIVaultRate = venusVAIVaultRate_;\n emit NewVenusVAIVaultRate(oldVenusVAIVaultRate, venusVAIVaultRate_);\n }\n\n /**\n * @notice Set the VAI Vault infos\n * @param vault_ The address of the VAI Vault\n * @param releaseStartBlock_ The start block of release to VAI Vault\n * @param minReleaseAmount_ The minimum release amount to VAI Vault\n */\n function _setVAIVaultInfo(\n address vault_,\n uint256 releaseStartBlock_,\n uint256 minReleaseAmount_\n ) external compareAddress(vaiVaultAddress, vault_) {\n ensureAdmin();\n ensureNonzeroAddress(vault_);\n if (vaiVaultAddress != address(0)) {\n releaseToVault();\n }\n\n vaiVaultAddress = vault_;\n releaseStartBlock = releaseStartBlock_;\n minReleaseAmount = minReleaseAmount_;\n emit NewVAIVaultInfo(vault_, releaseStartBlock_, minReleaseAmount_);\n }\n\n /**\n * @notice Sets the prime token contract for the comptroller\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPrimeToken(IPrime _prime) external returns (uint) {\n ensureAdmin();\n ensureNonzeroAddress(address(_prime));\n\n IPrime oldPrime = prime;\n prime = _prime;\n emit NewPrimeToken(oldPrime, _prime);\n\n return uint(Error.NO_ERROR);\n }\n\n /** @notice Enables forced liquidations for a market. If forced liquidation is enabled,\n * borrows in the market may be liquidated regardless of the account liquidity\n * @dev Allows a privileged role to set enable/disable forced liquidations\n * @param vTokenBorrowed Borrowed vToken\n * @param enable Whether to enable forced liquidations\n */\n function _setForcedLiquidation(address vTokenBorrowed, bool enable) external {\n ensureAllowed(\"_setForcedLiquidation(address,bool)\");\n if (vTokenBorrowed != address(vaiController)) {\n ensureListed(markets[vTokenBorrowed]);\n }\n isForcedLiquidationEnabled[vTokenBorrowed] = enable;\n emit IsForcedLiquidationEnabledUpdated(vTokenBorrowed, enable);\n }\n\n /**\n * @notice Enables forced liquidations for user's borrows in a certain market. If forced\n * liquidation is enabled, user's borrows in the market may be liquidated regardless of\n * the account liquidity. Forced liquidation may be enabled for a user even if it is not\n * enabled for the entire market.\n * @param borrower The address of the borrower\n * @param vTokenBorrowed Borrowed vToken\n * @param enable Whether to enable forced liquidations\n */\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external {\n ensureAllowed(\"_setForcedLiquidationForUser(address,address,bool)\");\n if (vTokenBorrowed != address(vaiController)) {\n ensureListed(markets[vTokenBorrowed]);\n }\n isForcedLiquidationEnabledForUser[borrower][vTokenBorrowed] = enable;\n emit IsForcedLiquidationEnabledForUserUpdated(borrower, vTokenBorrowed, enable);\n }\n\n /**\n * @notice Set the address of the XVS token\n * @param xvs_ The address of the XVS token\n */\n function _setXVSToken(address xvs_) external {\n ensureAdmin();\n ensureNonzeroAddress(xvs_);\n\n emit NewXVSToken(xvs, xvs_);\n xvs = xvs_;\n }\n\n /**\n * @notice Set the address of the XVS vToken\n * @param xvsVToken_ The address of the XVS vToken\n */\n function _setXVSVToken(address xvsVToken_) external {\n ensureAdmin();\n ensureNonzeroAddress(xvsVToken_);\n\n address underlying = VToken(xvsVToken_).underlying();\n require(underlying == xvs, \"invalid xvs vtoken address\");\n\n emit NewXVSVToken(xvsVToken, xvsVToken_);\n xvsVToken = xvsVToken_;\n }\n}\n" + }, + "contracts/Comptroller/Diamond/facets/XVSRewardsHelper.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { FacetBase } from \"./FacetBase.sol\";\n\n/**\n * @title XVSRewardsHelper\n * @author Venus\n * @dev This contract contains internal functions used in RewardFacet and PolicyFacet\n * @notice This facet contract contains the shared functions used by the RewardFacet and PolicyFacet\n */\ncontract XVSRewardsHelper is FacetBase {\n /// @notice Emitted when XVS is distributed to a borrower\n event DistributedBorrowerVenus(\n VToken indexed vToken,\n address indexed borrower,\n uint256 venusDelta,\n uint256 venusBorrowIndex\n );\n\n /// @notice Emitted when XVS is distributed to a supplier\n event DistributedSupplierVenus(\n VToken indexed vToken,\n address indexed supplier,\n uint256 venusDelta,\n uint256 venusSupplyIndex\n );\n\n /**\n * @notice Accrue XVS to the market by updating the borrow index\n * @param vToken The market whose borrow index to update\n */\n function updateVenusBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\n VenusMarketState storage borrowState = venusBorrowState[vToken];\n uint256 borrowSpeed = venusBorrowSpeeds[vToken];\n uint32 blockNumber = getBlockNumberAsUint32();\n uint256 deltaBlocks = sub_(blockNumber, borrowState.block);\n if (deltaBlocks != 0 && borrowSpeed != 0) {\n uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint256 accruedVenus = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount != 0 ? fraction(accruedVenus, borrowAmount) : Double({ mantissa: 0 });\n borrowState.index = safe224(add_(Double({ mantissa: borrowState.index }), ratio).mantissa, \"224\");\n borrowState.block = blockNumber;\n } else if (deltaBlocks != 0) {\n borrowState.block = blockNumber;\n }\n }\n\n /**\n * @notice Accrue XVS to the market by updating the supply index\n * @param vToken The market whose supply index to update\n */\n function updateVenusSupplyIndex(address vToken) internal {\n VenusMarketState storage supplyState = venusSupplyState[vToken];\n uint256 supplySpeed = venusSupplySpeeds[vToken];\n uint32 blockNumber = getBlockNumberAsUint32();\n\n uint256 deltaBlocks = sub_(blockNumber, supplyState.block);\n if (deltaBlocks != 0 && supplySpeed != 0) {\n uint256 supplyTokens = VToken(vToken).totalSupply();\n uint256 accruedVenus = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens != 0 ? fraction(accruedVenus, supplyTokens) : Double({ mantissa: 0 });\n supplyState.index = safe224(add_(Double({ mantissa: supplyState.index }), ratio).mantissa, \"224\");\n supplyState.block = blockNumber;\n } else if (deltaBlocks != 0) {\n supplyState.block = blockNumber;\n }\n }\n\n /**\n * @notice Calculate XVS accrued by a supplier and possibly transfer it to them\n * @param vToken The market in which the supplier is interacting\n * @param supplier The address of the supplier to distribute XVS to\n */\n function distributeSupplierVenus(address vToken, address supplier) internal {\n if (address(vaiVaultAddress) != address(0)) {\n releaseToVault();\n }\n uint256 supplyIndex = venusSupplyState[vToken].index;\n uint256 supplierIndex = venusSupplierIndex[vToken][supplier];\n // Update supplier's index to the current index since we are distributing accrued XVS\n venusSupplierIndex[vToken][supplier] = supplyIndex;\n if (supplierIndex == 0 && supplyIndex >= venusInitialIndex) {\n // Covers the case where users supplied tokens before the market's supply state index was set.\n // Rewards the user with XVS accrued from the start of when supplier rewards were first\n // set for the market.\n supplierIndex = venusInitialIndex;\n }\n // Calculate change in the cumulative sum of the XVS per vToken accrued\n Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\n // Multiply of supplierTokens and supplierDelta\n uint256 supplierDelta = mul_(VToken(vToken).balanceOf(supplier), deltaIndex);\n // Addition of supplierAccrued and supplierDelta\n venusAccrued[supplier] = add_(venusAccrued[supplier], supplierDelta);\n emit DistributedSupplierVenus(VToken(vToken), supplier, supplierDelta, supplyIndex);\n }\n\n /**\n * @notice Calculate XVS accrued by a borrower and possibly transfer it to them\n * @dev Borrowers will not begin to accrue until after the first interaction with the protocol\n * @param vToken The market in which the borrower is interacting\n * @param borrower The address of the borrower to distribute XVS to\n */\n function distributeBorrowerVenus(address vToken, address borrower, Exp memory marketBorrowIndex) internal {\n if (address(vaiVaultAddress) != address(0)) {\n releaseToVault();\n }\n uint256 borrowIndex = venusBorrowState[vToken].index;\n uint256 borrowerIndex = venusBorrowerIndex[vToken][borrower];\n // Update borrowers's index to the current index since we are distributing accrued XVS\n venusBorrowerIndex[vToken][borrower] = borrowIndex;\n if (borrowerIndex == 0 && borrowIndex >= venusInitialIndex) {\n // Covers the case where users borrowed tokens before the market's borrow state index was set.\n // Rewards the user with XVS accrued from the start of when borrower rewards were first\n // set for the market.\n borrowerIndex = venusInitialIndex;\n }\n // Calculate change in the cumulative sum of the XVS per borrowed unit accrued\n Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\n uint256 borrowerDelta = mul_(div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex), deltaIndex);\n venusAccrued[borrower] = add_(venusAccrued[borrower], borrowerDelta);\n emit DistributedBorrowerVenus(VToken(vToken), borrower, borrowerDelta, borrowIndex);\n }\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/IDiamondCut.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\npragma experimental ABIEncoderV2;\n\ninterface IDiamondCut {\n enum FacetCutAction {\n Add,\n Replace,\n Remove\n }\n // Add=0, Replace=1, Remove=2\n\n struct FacetCut {\n address facetAddress;\n FacetCutAction action;\n bytes4[] functionSelectors;\n }\n\n /// @notice Add/replace/remove any number of functions and optionally execute\n /// a function with delegatecall\n /// @param _diamondCut Contains the facet addresses and function selectors\n function diamondCut(FacetCut[] calldata _diamondCut) external;\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/IMarketFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\n\ninterface IMarketFacet {\n function isComptroller() external pure returns (bool);\n\n function liquidateCalculateSeizeTokens(\n address vTokenBorrowed,\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view returns (uint256, uint256);\n\n function liquidateVAICalculateSeizeTokens(\n address vTokenCollateral,\n uint256 actualRepayAmount\n ) external view returns (uint256, uint256);\n\n function checkMembership(address account, VToken vToken) external view returns (bool);\n\n function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\n\n function exitMarket(address vToken) external returns (uint256);\n\n function _supportMarket(VToken vToken) external returns (uint256);\n\n function getAssetsIn(address account) external view returns (VToken[] memory);\n\n function getAllMarkets() external view returns (VToken[] memory);\n\n function updateDelegate(address delegate, bool allowBorrows) external;\n\n function unlistMarket(address market) external returns (uint256);\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/IPolicyFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\n\ninterface IPolicyFacet {\n function mintAllowed(address vToken, address minter, uint256 mintAmount) external returns (uint256);\n\n function mintVerify(address vToken, address minter, uint256 mintAmount, uint256 mintTokens) external;\n\n function redeemAllowed(address vToken, address redeemer, uint256 redeemTokens) external returns (uint256);\n\n function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external;\n\n function borrowAllowed(address vToken, address borrower, uint256 borrowAmount) external returns (uint256);\n\n function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external;\n\n function repayBorrowAllowed(\n address vToken,\n address payer,\n address borrower,\n uint256 repayAmount\n ) external returns (uint256);\n\n function repayBorrowVerify(\n address vToken,\n address payer,\n address borrower,\n uint256 repayAmount,\n uint256 borrowerIndex\n ) external;\n\n function liquidateBorrowAllowed(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint256 repayAmount\n ) external view returns (uint256);\n\n function liquidateBorrowVerify(\n address vTokenBorrowed,\n address vTokenCollateral,\n address liquidator,\n address borrower,\n uint256 repayAmount,\n uint256 seizeTokens\n ) external;\n\n function seizeAllowed(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external returns (uint256);\n\n function seizeVerify(\n address vTokenCollateral,\n address vTokenBorrowed,\n address liquidator,\n address borrower,\n uint256 seizeTokens\n ) external;\n\n function transferAllowed(\n address vToken,\n address src,\n address dst,\n uint256 transferTokens\n ) external returns (uint256);\n\n function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external;\n\n function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);\n\n function getHypotheticalAccountLiquidity(\n address account,\n address vTokenModify,\n uint256 redeemTokens,\n uint256 borrowAmount\n ) external view returns (uint256, uint256, uint256);\n\n function _setVenusSpeeds(\n VToken[] calldata vTokens,\n uint256[] calldata supplySpeeds,\n uint256[] calldata borrowSpeeds\n ) external;\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/IRewardFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { ComptrollerTypes } from \"../../ComptrollerStorage.sol\";\n\ninterface IRewardFacet {\n function claimVenus(address holder) external;\n\n function claimVenus(address holder, VToken[] calldata vTokens) external;\n\n function claimVenus(address[] calldata holders, VToken[] calldata vTokens, bool borrowers, bool suppliers) external;\n\n function claimVenusAsCollateral(address holder) external;\n\n function _grantXVS(address recipient, uint256 amount) external;\n\n function getXVSAddress() external view returns (address);\n\n function getXVSVTokenAddress() external view returns (address);\n\n function actionPaused(address market, ComptrollerTypes.Action action) external view returns (bool);\n\n function claimVenus(\n address[] calldata holders,\n VToken[] calldata vTokens,\n bool borrowers,\n bool suppliers,\n bool collateral\n ) external;\n function seizeVenus(address[] calldata holders, address recipient) external returns (uint256);\n}\n" + }, + "contracts/Comptroller/Diamond/interfaces/ISetterFacet.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\n\nimport { PriceOracle } from \"../../../Oracle/PriceOracle.sol\";\nimport { VToken } from \"../../../Tokens/VTokens/VToken.sol\";\nimport { ComptrollerTypes } from \"../../ComptrollerStorage.sol\";\nimport { VAIControllerInterface } from \"../../../Tokens/VAI/VAIControllerInterface.sol\";\nimport { ComptrollerLensInterface } from \"../../../Comptroller/ComptrollerLensInterface.sol\";\nimport { IPrime } from \"../../../Tokens/Prime/IPrime.sol\";\n\ninterface ISetterFacet {\n function _setPriceOracle(PriceOracle newOracle) external returns (uint256);\n\n function _setCloseFactor(uint256 newCloseFactorMantissa) external returns (uint256);\n\n function _setAccessControl(address newAccessControlAddress) external returns (uint256);\n\n function _setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa) external returns (uint256);\n\n function _setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external returns (uint256);\n\n function _setLiquidatorContract(address newLiquidatorContract_) external;\n\n function _setPauseGuardian(address newPauseGuardian) external returns (uint256);\n\n function _setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external;\n\n function _setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external;\n\n function _setProtocolPaused(bool state) external returns (bool);\n\n function _setActionsPaused(\n address[] calldata markets,\n ComptrollerTypes.Action[] calldata actions,\n bool paused\n ) external;\n\n function _setVAIController(VAIControllerInterface vaiController_) external returns (uint256);\n\n function _setVAIMintRate(uint256 newVAIMintRate) external returns (uint256);\n\n function setMintedVAIOf(address owner, uint256 amount) external returns (uint256);\n\n function _setTreasuryData(\n address newTreasuryGuardian,\n address newTreasuryAddress,\n uint256 newTreasuryPercent\n ) external returns (uint256);\n\n function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint256);\n\n function _setVenusVAIVaultRate(uint256 venusVAIVaultRate_) external;\n\n function _setVAIVaultInfo(address vault_, uint256 releaseStartBlock_, uint256 minReleaseAmount_) external;\n\n function _setForcedLiquidation(address vToken, bool enable) external;\n\n function _setPrimeToken(IPrime _prime) external returns (uint);\n\n function _setForcedLiquidationForUser(address borrower, address vTokenBorrowed, bool enable) external;\n\n function _setXVSToken(address xvs_) external;\n\n function _setXVSVToken(address xvsVToken_) external;\n}\n" + }, + "contracts/Comptroller/Unitroller.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./ComptrollerStorage.sol\";\nimport \"../Utils/ErrorReporter.sol\";\n\n/**\n * @title ComptrollerCore\n * @dev Storage for the comptroller is at this address, while execution is delegated to the `comptrollerImplementation`.\n * VTokens should reference this contract as their comptroller.\n */\ncontract Unitroller is UnitrollerAdminStorage, ComptrollerErrorReporter {\n /**\n * @notice Emitted when pendingComptrollerImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingComptrollerImplementation is accepted, which means comptroller implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor() public {\n // Set admin to caller\n admin = msg.sender;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public returns (uint) {\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK);\n }\n\n address oldPendingImplementation = pendingComptrollerImplementation;\n\n pendingComptrollerImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingComptrollerImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts new implementation of comptroller. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public returns (uint) {\n // Check caller is pendingImplementation and pendingImplementation ≠ address(0)\n if (msg.sender != pendingComptrollerImplementation || pendingComptrollerImplementation == address(0)) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldImplementation = comptrollerImplementation;\n address oldPendingImplementation = pendingComptrollerImplementation;\n\n comptrollerImplementation = pendingComptrollerImplementation;\n\n pendingComptrollerImplementation = address(0);\n\n emit NewImplementation(oldImplementation, comptrollerImplementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingComptrollerImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public returns (uint) {\n // Check caller = admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK);\n }\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public returns (uint) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = comptrollerImplementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/Governance/VTreasury.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/IBEP20.sol\";\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/Ownable.sol\";\n\n/**\n * @title VTreasury\n * @author Venus\n * @notice Protocol treasury that holds tokens owned by Venus\n */\ncontract VTreasury is Ownable {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n // WithdrawTreasuryBEP20 Event\n event WithdrawTreasuryBEP20(address tokenAddress, uint256 withdrawAmount, address withdrawAddress);\n\n // WithdrawTreasuryBNB Event\n event WithdrawTreasuryBNB(uint256 withdrawAmount, address withdrawAddress);\n\n /**\n * @notice To receive BNB\n */\n function() external payable {}\n\n /**\n * @notice Withdraw Treasury BEP20 Tokens, Only owner call it\n * @param tokenAddress The address of treasury token\n * @param withdrawAmount The withdraw amount to owner\n * @param withdrawAddress The withdraw address\n */\n function withdrawTreasuryBEP20(\n address tokenAddress,\n uint256 withdrawAmount,\n address withdrawAddress\n ) external onlyOwner {\n uint256 actualWithdrawAmount = withdrawAmount;\n // Get Treasury Token Balance\n uint256 treasuryBalance = IBEP20(tokenAddress).balanceOf(address(this));\n\n // Check Withdraw Amount\n if (withdrawAmount > treasuryBalance) {\n // Update actualWithdrawAmount\n actualWithdrawAmount = treasuryBalance;\n }\n\n // Transfer BEP20 Token to withdrawAddress\n IBEP20(tokenAddress).safeTransfer(withdrawAddress, actualWithdrawAmount);\n\n emit WithdrawTreasuryBEP20(tokenAddress, actualWithdrawAmount, withdrawAddress);\n }\n\n /**\n * @notice Withdraw Treasury BNB, Only owner call it\n * @param withdrawAmount The withdraw amount to owner\n * @param withdrawAddress The withdraw address\n */\n function withdrawTreasuryBNB(uint256 withdrawAmount, address payable withdrawAddress) external payable onlyOwner {\n uint256 actualWithdrawAmount = withdrawAmount;\n // Get Treasury BNB Balance\n uint256 bnbBalance = address(this).balance;\n\n // Check Withdraw Amount\n if (withdrawAmount > bnbBalance) {\n // Update actualWithdrawAmount\n actualWithdrawAmount = bnbBalance;\n }\n // Transfer BNB to withdrawAddress\n withdrawAddress.transfer(actualWithdrawAmount);\n\n emit WithdrawTreasuryBNB(actualWithdrawAmount, withdrawAddress);\n }\n}\n" + }, + "contracts/InterestRateModels/InterestRateModel.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title Venus's InterestRateModel Interface\n * @author Venus\n */\ncontract InterestRateModel {\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\n bool public constant isInterestRateModel = true;\n\n /**\n * @notice Calculates the current borrow interest rate per block\n * @param cash The total amount of cash the market has\n * @param borrows The total amount of borrows the market has outstanding\n * @param reserves The total amnount of reserves the market has\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\n */\n function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);\n\n /**\n * @notice Calculates the current supply interest rate per block\n * @param cash The total amount of cash the market has\n * @param borrows The total amount of borrows the market has outstanding\n * @param reserves The total amnount of reserves the market has\n * @param reserveFactorMantissa The current reserve factor the market has\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\n */\n function getSupplyRate(\n uint cash,\n uint borrows,\n uint reserves,\n uint reserveFactorMantissa\n ) external view returns (uint);\n}\n" + }, + "contracts/InterestRateModels/JumpRateModel.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\nimport \"./InterestRateModel.sol\";\n\n/**\n * @title Venus's JumpRateModel Contract\n * @author Venus\n */\ncontract JumpRateModel is InterestRateModel {\n using SafeMath for uint;\n\n event NewInterestParams(uint baseRatePerBlock, uint multiplierPerBlock, uint jumpMultiplierPerBlock, uint kink);\n\n /**\n * @notice The approximate number of blocks per year that is assumed by the interest rate model\n */\n uint public constant blocksPerYear = (60 * 60 * 24 * 365) / 3; // (assuming 3s blocks)\n\n /**\n * @notice The multiplier of utilization rate that gives the slope of the interest rate\n */\n uint public multiplierPerBlock;\n\n /**\n * @notice The base interest rate which is the y-intercept when utilization rate is 0\n */\n uint public baseRatePerBlock;\n\n /**\n * @notice The multiplierPerBlock after hitting a specified utilization point\n */\n uint public jumpMultiplierPerBlock;\n\n /**\n * @notice The utilization point at which the jump multiplier is applied\n */\n uint public kink;\n\n /**\n * @notice Construct an interest rate model\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by 1e18)\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by 1e18)\n * @param jumpMultiplierPerYear The multiplierPerBlock after hitting a specified utilization point\n * @param kink_ The utilization point at which the jump multiplier is applied\n */\n constructor(uint baseRatePerYear, uint multiplierPerYear, uint jumpMultiplierPerYear, uint kink_) public {\n baseRatePerBlock = baseRatePerYear.div(blocksPerYear);\n multiplierPerBlock = multiplierPerYear.div(blocksPerYear);\n jumpMultiplierPerBlock = jumpMultiplierPerYear.div(blocksPerYear);\n kink = kink_;\n\n emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink);\n }\n\n /**\n * @notice Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market (currently unused)\n * @return The utilization rate as a mantissa between [0, 1e18]\n */\n function utilizationRate(uint cash, uint borrows, uint reserves) public pure returns (uint) {\n // Utilization rate is 0 when there are no borrows\n if (borrows == 0) {\n return 0;\n }\n\n return borrows.mul(1e18).div(cash.add(borrows).sub(reserves));\n }\n\n /**\n * @notice Calculates the current borrow rate per block, with the error code expected by the market\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market\n * @return The borrow rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getBorrowRate(uint cash, uint borrows, uint reserves) public view returns (uint) {\n uint util = utilizationRate(cash, borrows, reserves);\n\n if (util <= kink) {\n return util.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);\n } else {\n uint normalRate = kink.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);\n uint excessUtil = util.sub(kink);\n return excessUtil.mul(jumpMultiplierPerBlock).div(1e18).add(normalRate);\n }\n }\n\n /**\n * @notice Calculates the current supply rate per block\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market\n * @param reserveFactorMantissa The current reserve factor for the market\n * @return The supply rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getSupplyRate(\n uint cash,\n uint borrows,\n uint reserves,\n uint reserveFactorMantissa\n ) public view returns (uint) {\n uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa);\n uint borrowRate = getBorrowRate(cash, borrows, reserves);\n uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18);\n return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18);\n }\n}\n" + }, + "contracts/InterestRateModels/WhitePaperInterestRateModel.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\nimport \"./InterestRateModel.sol\";\n\n/**\n * @title Venus's WhitePaperInterestRateModel Contract\n * @author Venus\n * @notice The parameterized model described in section 2.4 of the original Venus Protocol whitepaper\n */\ncontract WhitePaperInterestRateModel is InterestRateModel {\n using SafeMath for uint;\n\n event NewInterestParams(uint baseRatePerBlock, uint multiplierPerBlock);\n\n /**\n * @notice The approximate number of blocks per year that is assumed by the interest rate model\n */\n uint public constant blocksPerYear = (60 * 60 * 24 * 365) / 3; // (assuming 3s blocks)\n\n /**\n * @notice The multiplier of utilization rate that gives the slope of the interest rate\n */\n uint public multiplierPerBlock;\n\n /**\n * @notice The base interest rate which is the y-intercept when utilization rate is 0\n */\n uint public baseRatePerBlock;\n\n /**\n * @notice Construct an interest rate model\n * @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by 1e18)\n * @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by 1e18)\n */\n constructor(uint baseRatePerYear, uint multiplierPerYear) public {\n baseRatePerBlock = baseRatePerYear.div(blocksPerYear);\n multiplierPerBlock = multiplierPerYear.div(blocksPerYear);\n\n emit NewInterestParams(baseRatePerBlock, multiplierPerBlock);\n }\n\n /**\n * @notice Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market (currently unused)\n * @return The utilization rate as a mantissa between [0, 1e18]\n */\n function utilizationRate(uint cash, uint borrows, uint reserves) public pure returns (uint) {\n // Utilization rate is 0 when there are no borrows\n if (borrows == 0) {\n return 0;\n }\n\n return borrows.mul(1e18).div(cash.add(borrows).sub(reserves));\n }\n\n /**\n * @notice Calculates the current borrow rate per block, with the error code expected by the market\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market\n * @return The borrow rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getBorrowRate(uint cash, uint borrows, uint reserves) public view returns (uint) {\n uint ur = utilizationRate(cash, borrows, reserves);\n return ur.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);\n }\n\n /**\n * @notice Calculates the current supply rate per block\n * @param cash The amount of cash in the market\n * @param borrows The amount of borrows in the market\n * @param reserves The amount of reserves in the market\n * @param reserveFactorMantissa The current reserve factor for the market\n * @return The supply rate percentage per block as a mantissa (scaled by 1e18)\n */\n function getSupplyRate(\n uint cash,\n uint borrows,\n uint reserves,\n uint reserveFactorMantissa\n ) public view returns (uint) {\n uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa);\n uint borrowRate = getBorrowRate(cash, borrows, reserves);\n uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18);\n return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18);\n }\n}\n" + }, + "contracts/Lens/ComptrollerLens.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Tokens/VTokens/VBep20.sol\";\nimport { VToken } from \"../Tokens/VTokens/VToken.sol\";\nimport { ExponentialNoError } from \"../Utils/ExponentialNoError.sol\";\nimport \"../Tokens/EIP20Interface.sol\";\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Utils/ErrorReporter.sol\";\nimport \"../Comptroller/ComptrollerInterface.sol\";\nimport \"../Comptroller/ComptrollerLensInterface.sol\";\nimport \"../Tokens/VAI/VAIControllerInterface.sol\";\n\n/**\n * @title ComptrollerLens Contract\n * @author Venus\n * @notice The ComptrollerLens contract has functions to get the number of tokens that\n * can be seized through liquidation, hypothetical account liquidity and shortfall of an account.\n */\ncontract ComptrollerLens is ComptrollerLensInterface, ComptrollerErrorReporter, ExponentialNoError {\n /**\n * @dev Local vars for avoiding stack-depth limits in calculating account liquidity.\n * Note that `vTokenBalance` is the number of vTokens the account owns in the market,\n * whereas `borrowBalance` is the amount of underlying that the account has borrowed.\n */\n struct AccountLiquidityLocalVars {\n uint sumCollateral;\n uint sumBorrowPlusEffects;\n uint vTokenBalance;\n uint borrowBalance;\n uint exchangeRateMantissa;\n uint oraclePriceMantissa;\n Exp collateralFactor;\n Exp exchangeRate;\n Exp oraclePrice;\n Exp tokensToDenom;\n }\n\n /**\n * @notice Computes the number of collateral tokens to be seized in a liquidation event\n * @param comptroller Address of comptroller\n * @param vTokenBorrowed Address of the borrowed vToken\n * @param vTokenCollateral Address of collateral for the borrow\n * @param actualRepayAmount Repayment amount i.e amount to be repaid of total borrowed amount\n * @return A tuple of error code, and tokens to seize\n */\n function liquidateCalculateSeizeTokens(\n address comptroller,\n address vTokenBorrowed,\n address vTokenCollateral,\n uint actualRepayAmount\n ) external view returns (uint, uint) {\n /* Read oracle prices for borrowed and collateral markets */\n uint priceBorrowedMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(\n VToken(vTokenBorrowed)\n );\n uint priceCollateralMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(\n VToken(vTokenCollateral)\n );\n if (priceBorrowedMantissa == 0 || priceCollateralMantissa == 0) {\n return (uint(Error.PRICE_ERROR), 0);\n }\n\n /*\n * Get the exchange rate and calculate the number of collateral tokens to seize:\n * seizeAmount = actualRepayAmount * liquidationIncentive * priceBorrowed / priceCollateral\n * seizeTokens = seizeAmount / exchangeRate\n * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate)\n */\n uint exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\n uint seizeTokens;\n Exp memory numerator;\n Exp memory denominator;\n Exp memory ratio;\n\n numerator = mul_(\n Exp({ mantissa: ComptrollerInterface(comptroller).liquidationIncentiveMantissa() }),\n Exp({ mantissa: priceBorrowedMantissa })\n );\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\n ratio = div_(numerator, denominator);\n\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\n\n return (uint(Error.NO_ERROR), seizeTokens);\n }\n\n /**\n * @notice Computes the number of VAI tokens to be seized in a liquidation event\n * @param comptroller Address of comptroller\n * @param vTokenCollateral Address of collateral for vToken\n * @param actualRepayAmount Repayment amount i.e amount to be repaid of the total borrowed amount\n * @return A tuple of error code, and tokens to seize\n */\n function liquidateVAICalculateSeizeTokens(\n address comptroller,\n address vTokenCollateral,\n uint actualRepayAmount\n ) external view returns (uint, uint) {\n /* Read oracle prices for borrowed and collateral markets */\n uint priceBorrowedMantissa = 1e18; // Note: this is VAI\n uint priceCollateralMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(\n VToken(vTokenCollateral)\n );\n if (priceCollateralMantissa == 0) {\n return (uint(Error.PRICE_ERROR), 0);\n }\n\n /*\n * Get the exchange rate and calculate the number of collateral tokens to seize:\n * seizeAmount = actualRepayAmount * liquidationIncentive * priceBorrowed / priceCollateral\n * seizeTokens = seizeAmount / exchangeRate\n * = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate)\n */\n uint exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\n uint seizeTokens;\n Exp memory numerator;\n Exp memory denominator;\n Exp memory ratio;\n\n numerator = mul_(\n Exp({ mantissa: ComptrollerInterface(comptroller).liquidationIncentiveMantissa() }),\n Exp({ mantissa: priceBorrowedMantissa })\n );\n denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\n ratio = div_(numerator, denominator);\n\n seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\n\n return (uint(Error.NO_ERROR), seizeTokens);\n }\n\n /**\n * @notice Computes the hypothetical liquidity and shortfall of an account given a hypothetical borrow\n * A snapshot of the account is taken and the total borrow amount of the account is calculated\n * @param comptroller Address of comptroller\n * @param account Address of the borrowed vToken\n * @param vTokenModify Address of collateral for vToken\n * @param redeemTokens Number of vTokens being redeemed\n * @param borrowAmount Amount borrowed\n * @return Returns a tuple of error code, liquidity, and shortfall\n */\n function getHypotheticalAccountLiquidity(\n address comptroller,\n address account,\n VToken vTokenModify,\n uint redeemTokens,\n uint borrowAmount\n ) external view returns (uint, uint, uint) {\n AccountLiquidityLocalVars memory vars; // Holds all our calculation results\n uint oErr;\n\n // For each asset the account is in\n VToken[] memory assets = ComptrollerInterface(comptroller).getAssetsIn(account);\n uint assetsCount = assets.length;\n for (uint i = 0; i < assetsCount; ++i) {\n VToken asset = assets[i];\n\n // Read the balances and exchange rate from the vToken\n (oErr, vars.vTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = asset.getAccountSnapshot(\n account\n );\n if (oErr != 0) {\n // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades\n return (uint(Error.SNAPSHOT_ERROR), 0, 0);\n }\n (, uint collateralFactorMantissa) = ComptrollerInterface(comptroller).markets(address(asset));\n vars.collateralFactor = Exp({ mantissa: collateralFactorMantissa });\n vars.exchangeRate = Exp({ mantissa: vars.exchangeRateMantissa });\n\n // Get the normalized price of the asset\n vars.oraclePriceMantissa = ComptrollerInterface(comptroller).oracle().getUnderlyingPrice(asset);\n if (vars.oraclePriceMantissa == 0) {\n return (uint(Error.PRICE_ERROR), 0, 0);\n }\n vars.oraclePrice = Exp({ mantissa: vars.oraclePriceMantissa });\n\n // Pre-compute a conversion factor from tokens -> bnb (normalized price value)\n vars.tokensToDenom = mul_(mul_(vars.collateralFactor, vars.exchangeRate), vars.oraclePrice);\n\n // sumCollateral += tokensToDenom * vTokenBalance\n vars.sumCollateral = mul_ScalarTruncateAddUInt(vars.tokensToDenom, vars.vTokenBalance, vars.sumCollateral);\n\n // sumBorrowPlusEffects += oraclePrice * borrowBalance\n vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(\n vars.oraclePrice,\n vars.borrowBalance,\n vars.sumBorrowPlusEffects\n );\n\n // Calculate effects of interacting with vTokenModify\n if (asset == vTokenModify) {\n // redeem effect\n // sumBorrowPlusEffects += tokensToDenom * redeemTokens\n vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(\n vars.tokensToDenom,\n redeemTokens,\n vars.sumBorrowPlusEffects\n );\n\n // borrow effect\n // sumBorrowPlusEffects += oraclePrice * borrowAmount\n vars.sumBorrowPlusEffects = mul_ScalarTruncateAddUInt(\n vars.oraclePrice,\n borrowAmount,\n vars.sumBorrowPlusEffects\n );\n }\n }\n\n VAIControllerInterface vaiController = ComptrollerInterface(comptroller).vaiController();\n\n if (address(vaiController) != address(0)) {\n vars.sumBorrowPlusEffects = add_(vars.sumBorrowPlusEffects, vaiController.getVAIRepayAmount(account));\n }\n\n // These are safe, as the underflow condition is checked first\n if (vars.sumCollateral > vars.sumBorrowPlusEffects) {\n return (uint(Error.NO_ERROR), vars.sumCollateral - vars.sumBorrowPlusEffects, 0);\n } else {\n return (uint(Error.NO_ERROR), 0, vars.sumBorrowPlusEffects - vars.sumCollateral);\n }\n }\n}\n" + }, + "contracts/Lens/SnapshotLens.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport { VToken } from \"../Tokens/VTokens/VToken.sol\";\nimport { ExponentialNoError } from \"../Utils/ExponentialNoError.sol\";\nimport \"../Utils/SafeMath.sol\";\nimport \"../Comptroller/ComptrollerInterface.sol\";\nimport \"../Tokens/EIP20Interface.sol\";\nimport \"../Tokens/VTokens/VBep20.sol\";\n\ncontract SnapshotLens is ExponentialNoError {\n using SafeMath for uint256;\n\n struct AccountSnapshot {\n address account;\n string assetName;\n address vTokenAddress;\n address underlyingAssetAddress;\n uint256 supply;\n uint256 supplyInUsd;\n uint256 collateral;\n uint256 borrows;\n uint256 borrowsInUsd;\n uint256 assetPrice;\n uint256 accruedInterest;\n uint vTokenDecimals;\n uint underlyingDecimals;\n uint exchangeRate;\n bool isACollateral;\n }\n\n /** Snapshot calculation **/\n /**\n * @dev Local vars for avoiding stack-depth limits in calculating account snapshot.\n * Note that `vTokenBalance` is the number of vTokens the account owns in the market,\n * whereas `borrowBalance` is the amount of underlying that the account has borrowed.\n */\n struct AccountSnapshotLocalVars {\n uint collateral;\n uint vTokenBalance;\n uint borrowBalance;\n uint borrowsInUsd;\n uint balanceOfUnderlying;\n uint supplyInUsd;\n uint exchangeRateMantissa;\n uint oraclePriceMantissa;\n Exp collateralFactor;\n Exp exchangeRate;\n Exp oraclePrice;\n Exp tokensToDenom;\n bool isACollateral;\n }\n\n function getAccountSnapshot(\n address payable account,\n address comptrollerAddress\n ) public returns (AccountSnapshot[] memory) {\n // For each asset the account is in\n VToken[] memory assets = ComptrollerInterface(comptrollerAddress).getAllMarkets();\n AccountSnapshot[] memory accountSnapshots = new AccountSnapshot[](assets.length);\n for (uint256 i = 0; i < assets.length; ++i) {\n accountSnapshots[i] = getAccountSnapshot(account, comptrollerAddress, assets[i]);\n }\n return accountSnapshots;\n }\n\n function isACollateral(address account, address asset, address comptrollerAddress) public view returns (bool) {\n VToken[] memory assetsAsCollateral = ComptrollerInterface(comptrollerAddress).getAssetsIn(account);\n for (uint256 j = 0; j < assetsAsCollateral.length; ++j) {\n if (address(assetsAsCollateral[j]) == asset) {\n return true;\n }\n }\n\n return false;\n }\n\n function getAccountSnapshot(\n address payable account,\n address comptrollerAddress,\n VToken vToken\n ) public returns (AccountSnapshot memory) {\n AccountSnapshotLocalVars memory vars; // Holds all our calculation results\n uint oErr;\n\n // Read the balances and exchange rate from the vToken\n (oErr, vars.vTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = vToken.getAccountSnapshot(account);\n require(oErr == 0, \"Snapshot Error\");\n vars.exchangeRate = Exp({ mantissa: vars.exchangeRateMantissa });\n\n (, uint collateralFactorMantissa) = ComptrollerInterface(comptrollerAddress).markets(address(vToken));\n vars.collateralFactor = Exp({ mantissa: collateralFactorMantissa });\n\n // Get the normalized price of the asset\n vars.oraclePriceMantissa = ComptrollerInterface(comptrollerAddress).oracle().getUnderlyingPrice(vToken);\n vars.oraclePrice = Exp({ mantissa: vars.oraclePriceMantissa });\n\n // Pre-compute a conversion factor from tokens -> bnb (normalized price value)\n vars.tokensToDenom = mul_(mul_(vars.collateralFactor, vars.exchangeRate), vars.oraclePrice);\n\n //Collateral = tokensToDenom * vTokenBalance\n vars.collateral = mul_ScalarTruncate(vars.tokensToDenom, vars.vTokenBalance);\n\n vars.balanceOfUnderlying = vToken.balanceOfUnderlying(account);\n vars.supplyInUsd = mul_ScalarTruncate(vars.oraclePrice, vars.balanceOfUnderlying);\n\n vars.borrowsInUsd = mul_ScalarTruncate(vars.oraclePrice, vars.borrowBalance);\n\n address underlyingAssetAddress;\n uint underlyingDecimals;\n\n if (compareStrings(vToken.symbol(), \"vBNB\")) {\n underlyingAssetAddress = address(0);\n underlyingDecimals = 18;\n } else {\n VBep20 vBep20 = VBep20(address(vToken));\n underlyingAssetAddress = vBep20.underlying();\n underlyingDecimals = EIP20Interface(vBep20.underlying()).decimals();\n }\n\n vars.isACollateral = isACollateral(account, address(vToken), comptrollerAddress);\n\n return\n AccountSnapshot({\n account: account,\n assetName: vToken.name(),\n vTokenAddress: address(vToken),\n underlyingAssetAddress: underlyingAssetAddress,\n supply: vars.balanceOfUnderlying,\n supplyInUsd: vars.supplyInUsd,\n collateral: vars.collateral,\n borrows: vars.borrowBalance,\n borrowsInUsd: vars.borrowsInUsd,\n assetPrice: vars.oraclePriceMantissa,\n accruedInterest: vToken.borrowIndex(),\n vTokenDecimals: vToken.decimals(),\n underlyingDecimals: underlyingDecimals,\n exchangeRate: vToken.exchangeRateCurrent(),\n isACollateral: vars.isACollateral\n });\n }\n\n // utilities\n function compareStrings(string memory a, string memory b) internal pure returns (bool) {\n return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));\n }\n}\n" + }, + "contracts/Lens/VenusLens.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Tokens/VTokens/VBep20.sol\";\nimport \"../Tokens/VTokens/VToken.sol\";\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Tokens/EIP20Interface.sol\";\nimport \"../Tokens/XVS/XVS.sol\";\nimport \"../Comptroller/ComptrollerInterface.sol\";\nimport \"../Utils/SafeMath.sol\";\nimport { ComptrollerTypes } from \"../Comptroller/ComptrollerStorage.sol\";\n\ncontract VenusLens is ExponentialNoError {\n using SafeMath for uint;\n\n /// @notice Blocks Per Day\n uint public constant BLOCKS_PER_DAY = 28800;\n\n /// @notice Total actions available on VToken\n uint public constant VTOKEN_ACTIONS = 8;\n\n struct VenusMarketState {\n uint224 index;\n uint32 block;\n }\n\n struct VTokenMetadata {\n address vToken;\n uint exchangeRateCurrent;\n uint supplyRatePerBlock;\n uint borrowRatePerBlock;\n uint reserveFactorMantissa;\n uint totalBorrows;\n uint totalReserves;\n uint totalSupply;\n uint totalCash;\n bool isListed;\n uint collateralFactorMantissa;\n address underlyingAssetAddress;\n uint vTokenDecimals;\n uint underlyingDecimals;\n uint venusSupplySpeed;\n uint venusBorrowSpeed;\n uint dailySupplyXvs;\n uint dailyBorrowXvs;\n uint pausedActions;\n }\n\n struct VTokenBalances {\n address vToken;\n uint balanceOf;\n uint borrowBalanceCurrent;\n uint balanceOfUnderlying;\n uint tokenBalance;\n uint tokenAllowance;\n }\n\n struct VTokenUnderlyingPrice {\n address vToken;\n uint underlyingPrice;\n }\n\n struct AccountLimits {\n VToken[] markets;\n uint liquidity;\n uint shortfall;\n }\n\n struct XVSBalanceMetadata {\n uint balance;\n uint votes;\n address delegate;\n }\n\n struct XVSBalanceMetadataExt {\n uint balance;\n uint votes;\n address delegate;\n uint allocated;\n }\n\n struct VenusVotes {\n uint blockNumber;\n uint votes;\n }\n\n struct ClaimVenusLocalVariables {\n uint totalRewards;\n uint224 borrowIndex;\n uint32 borrowBlock;\n uint224 supplyIndex;\n uint32 supplyBlock;\n }\n\n /**\n * @dev Struct for Pending Rewards for per market\n */\n struct PendingReward {\n address vTokenAddress;\n uint256 amount;\n }\n\n /**\n * @dev Struct for Reward of a single reward token.\n */\n struct RewardSummary {\n address distributorAddress;\n address rewardTokenAddress;\n uint256 totalRewards;\n PendingReward[] pendingRewards;\n }\n\n /**\n * @notice Query the metadata of a vToken by its address\n * @param vToken The address of the vToken to fetch VTokenMetadata\n * @return VTokenMetadata struct with vToken supply and borrow information.\n */\n function vTokenMetadata(VToken vToken) public returns (VTokenMetadata memory) {\n uint exchangeRateCurrent = vToken.exchangeRateCurrent();\n address comptrollerAddress = address(vToken.comptroller());\n ComptrollerInterface comptroller = ComptrollerInterface(comptrollerAddress);\n (bool isListed, uint collateralFactorMantissa) = comptroller.markets(address(vToken));\n address underlyingAssetAddress;\n uint underlyingDecimals;\n\n if (compareStrings(vToken.symbol(), \"vBNB\")) {\n underlyingAssetAddress = address(0);\n underlyingDecimals = 18;\n } else {\n VBep20 vBep20 = VBep20(address(vToken));\n underlyingAssetAddress = vBep20.underlying();\n underlyingDecimals = EIP20Interface(vBep20.underlying()).decimals();\n }\n\n uint venusSupplySpeedPerBlock = comptroller.venusSupplySpeeds(address(vToken));\n uint venusBorrowSpeedPerBlock = comptroller.venusBorrowSpeeds(address(vToken));\n\n uint256 pausedActions;\n\n for (uint8 i; i <= VTOKEN_ACTIONS; ++i) {\n uint256 paused = comptroller.actionPaused(address(vToken), ComptrollerTypes.Action(i)) ? 1 : 0;\n pausedActions |= paused << i;\n }\n\n return\n VTokenMetadata({\n vToken: address(vToken),\n exchangeRateCurrent: exchangeRateCurrent,\n supplyRatePerBlock: vToken.supplyRatePerBlock(),\n borrowRatePerBlock: vToken.borrowRatePerBlock(),\n reserveFactorMantissa: vToken.reserveFactorMantissa(),\n totalBorrows: vToken.totalBorrows(),\n totalReserves: vToken.totalReserves(),\n totalSupply: vToken.totalSupply(),\n totalCash: vToken.getCash(),\n isListed: isListed,\n collateralFactorMantissa: collateralFactorMantissa,\n underlyingAssetAddress: underlyingAssetAddress,\n vTokenDecimals: vToken.decimals(),\n underlyingDecimals: underlyingDecimals,\n venusSupplySpeed: venusSupplySpeedPerBlock,\n venusBorrowSpeed: venusBorrowSpeedPerBlock,\n dailySupplyXvs: venusSupplySpeedPerBlock.mul(BLOCKS_PER_DAY),\n dailyBorrowXvs: venusBorrowSpeedPerBlock.mul(BLOCKS_PER_DAY),\n pausedActions: pausedActions\n });\n }\n\n /**\n * @notice Get VTokenMetadata for an array of vToken addresses\n * @param vTokens Array of vToken addresses to fetch VTokenMetadata\n * @return Array of structs with vToken supply and borrow information.\n */\n function vTokenMetadataAll(VToken[] calldata vTokens) external returns (VTokenMetadata[] memory) {\n uint vTokenCount = vTokens.length;\n VTokenMetadata[] memory res = new VTokenMetadata[](vTokenCount);\n for (uint i = 0; i < vTokenCount; i++) {\n res[i] = vTokenMetadata(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Get amount of XVS distributed daily to an account\n * @param account Address of account to fetch the daily XVS distribution\n * @param comptrollerAddress Address of the comptroller proxy\n * @return Amount of XVS distributed daily to an account\n */\n function getDailyXVS(address payable account, address comptrollerAddress) external returns (uint) {\n ComptrollerInterface comptrollerInstance = ComptrollerInterface(comptrollerAddress);\n VToken[] memory vTokens = comptrollerInstance.getAllMarkets();\n uint dailyXvsPerAccount = 0;\n\n for (uint i = 0; i < vTokens.length; i++) {\n VToken vToken = vTokens[i];\n if (!compareStrings(vToken.symbol(), \"vUST\") && !compareStrings(vToken.symbol(), \"vLUNA\")) {\n VTokenMetadata memory metaDataItem = vTokenMetadata(vToken);\n\n //get balanceOfUnderlying and borrowBalanceCurrent from vTokenBalance\n VTokenBalances memory vTokenBalanceInfo = vTokenBalances(vToken, account);\n\n VTokenUnderlyingPrice memory underlyingPriceResponse = vTokenUnderlyingPrice(vToken);\n uint underlyingPrice = underlyingPriceResponse.underlyingPrice;\n Exp memory underlyingPriceMantissa = Exp({ mantissa: underlyingPrice });\n\n //get dailyXvsSupplyMarket\n uint dailyXvsSupplyMarket = 0;\n uint supplyInUsd = mul_ScalarTruncate(underlyingPriceMantissa, vTokenBalanceInfo.balanceOfUnderlying);\n uint marketTotalSupply = (metaDataItem.totalSupply.mul(metaDataItem.exchangeRateCurrent)).div(1e18);\n uint marketTotalSupplyInUsd = mul_ScalarTruncate(underlyingPriceMantissa, marketTotalSupply);\n\n if (marketTotalSupplyInUsd > 0) {\n dailyXvsSupplyMarket = (metaDataItem.dailySupplyXvs.mul(supplyInUsd)).div(marketTotalSupplyInUsd);\n }\n\n //get dailyXvsBorrowMarket\n uint dailyXvsBorrowMarket = 0;\n uint borrowsInUsd = mul_ScalarTruncate(underlyingPriceMantissa, vTokenBalanceInfo.borrowBalanceCurrent);\n uint marketTotalBorrowsInUsd = mul_ScalarTruncate(underlyingPriceMantissa, metaDataItem.totalBorrows);\n\n if (marketTotalBorrowsInUsd > 0) {\n dailyXvsBorrowMarket = (metaDataItem.dailyBorrowXvs.mul(borrowsInUsd)).div(marketTotalBorrowsInUsd);\n }\n\n dailyXvsPerAccount += dailyXvsSupplyMarket + dailyXvsBorrowMarket;\n }\n }\n\n return dailyXvsPerAccount;\n }\n\n /**\n * @notice Get the current vToken balance (outstanding borrows) for an account\n * @param vToken Address of the token to check the balance of\n * @param account Account address to fetch the balance of\n * @return VTokenBalances with token balance information\n */\n function vTokenBalances(VToken vToken, address payable account) public returns (VTokenBalances memory) {\n uint balanceOf = vToken.balanceOf(account);\n uint borrowBalanceCurrent = vToken.borrowBalanceCurrent(account);\n uint balanceOfUnderlying = vToken.balanceOfUnderlying(account);\n uint tokenBalance;\n uint tokenAllowance;\n\n if (compareStrings(vToken.symbol(), \"vBNB\")) {\n tokenBalance = account.balance;\n tokenAllowance = account.balance;\n } else {\n VBep20 vBep20 = VBep20(address(vToken));\n EIP20Interface underlying = EIP20Interface(vBep20.underlying());\n tokenBalance = underlying.balanceOf(account);\n tokenAllowance = underlying.allowance(account, address(vToken));\n }\n\n return\n VTokenBalances({\n vToken: address(vToken),\n balanceOf: balanceOf,\n borrowBalanceCurrent: borrowBalanceCurrent,\n balanceOfUnderlying: balanceOfUnderlying,\n tokenBalance: tokenBalance,\n tokenAllowance: tokenAllowance\n });\n }\n\n /**\n * @notice Get the current vToken balances (outstanding borrows) for all vTokens on an account\n * @param vTokens Addresses of the tokens to check the balance of\n * @param account Account address to fetch the balance of\n * @return VTokenBalances Array with token balance information\n */\n function vTokenBalancesAll(\n VToken[] calldata vTokens,\n address payable account\n ) external returns (VTokenBalances[] memory) {\n uint vTokenCount = vTokens.length;\n VTokenBalances[] memory res = new VTokenBalances[](vTokenCount);\n for (uint i = 0; i < vTokenCount; i++) {\n res[i] = vTokenBalances(vTokens[i], account);\n }\n return res;\n }\n\n /**\n * @notice Get the price for the underlying asset of a vToken\n * @param vToken address of the vToken\n * @return response struct with underlyingPrice info of vToken\n */\n function vTokenUnderlyingPrice(VToken vToken) public view returns (VTokenUnderlyingPrice memory) {\n ComptrollerInterface comptroller = ComptrollerInterface(address(vToken.comptroller()));\n PriceOracle priceOracle = comptroller.oracle();\n\n return\n VTokenUnderlyingPrice({ vToken: address(vToken), underlyingPrice: priceOracle.getUnderlyingPrice(vToken) });\n }\n\n /**\n * @notice Query the underlyingPrice of an array of vTokens\n * @param vTokens Array of vToken addresses\n * @return array of response structs with underlying price information of vTokens\n */\n function vTokenUnderlyingPriceAll(\n VToken[] calldata vTokens\n ) external view returns (VTokenUnderlyingPrice[] memory) {\n uint vTokenCount = vTokens.length;\n VTokenUnderlyingPrice[] memory res = new VTokenUnderlyingPrice[](vTokenCount);\n for (uint i = 0; i < vTokenCount; i++) {\n res[i] = vTokenUnderlyingPrice(vTokens[i]);\n }\n return res;\n }\n\n /**\n * @notice Query the account liquidity and shortfall of an account\n * @param comptroller Address of comptroller proxy\n * @param account Address of the account to query\n * @return Struct with markets user has entered, liquidity, and shortfall of the account\n */\n function getAccountLimits(\n ComptrollerInterface comptroller,\n address account\n ) public view returns (AccountLimits memory) {\n (uint errorCode, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(account);\n require(errorCode == 0, \"account liquidity error\");\n\n return AccountLimits({ markets: comptroller.getAssetsIn(account), liquidity: liquidity, shortfall: shortfall });\n }\n\n /**\n * @notice Query the XVSBalance info of an account\n * @param xvs XVS contract address\n * @param account Account address\n * @return Struct with XVS balance and voter details\n */\n function getXVSBalanceMetadata(XVS xvs, address account) external view returns (XVSBalanceMetadata memory) {\n return\n XVSBalanceMetadata({\n balance: xvs.balanceOf(account),\n votes: uint256(xvs.getCurrentVotes(account)),\n delegate: xvs.delegates(account)\n });\n }\n\n /**\n * @notice Query the XVSBalance extended info of an account\n * @param xvs XVS contract address\n * @param comptroller Comptroller proxy contract address\n * @param account Account address\n * @return Struct with XVS balance and voter details and XVS allocation\n */\n function getXVSBalanceMetadataExt(\n XVS xvs,\n ComptrollerInterface comptroller,\n address account\n ) external returns (XVSBalanceMetadataExt memory) {\n uint balance = xvs.balanceOf(account);\n comptroller.claimVenus(account);\n uint newBalance = xvs.balanceOf(account);\n uint accrued = comptroller.venusAccrued(account);\n uint total = add_(accrued, newBalance, \"sum xvs total\");\n uint allocated = sub_(total, balance, \"sub allocated\");\n\n return\n XVSBalanceMetadataExt({\n balance: balance,\n votes: uint256(xvs.getCurrentVotes(account)),\n delegate: xvs.delegates(account),\n allocated: allocated\n });\n }\n\n /**\n * @notice Query the voting power for an account at a specific list of block numbers\n * @param xvs XVS contract address\n * @param account Address of the account\n * @param blockNumbers Array of blocks to query\n * @return Array of VenusVotes structs with block number and vote count\n */\n function getVenusVotes(\n XVS xvs,\n address account,\n uint32[] calldata blockNumbers\n ) external view returns (VenusVotes[] memory) {\n VenusVotes[] memory res = new VenusVotes[](blockNumbers.length);\n for (uint i = 0; i < blockNumbers.length; i++) {\n res[i] = VenusVotes({\n blockNumber: uint256(blockNumbers[i]),\n votes: uint256(xvs.getPriorVotes(account, blockNumbers[i]))\n });\n }\n return res;\n }\n\n /**\n * @dev Queries the current supply to calculate rewards for an account\n * @param supplyState VenusMarketState struct\n * @param vToken Address of a vToken\n * @param comptroller Address of the comptroller proxy\n */\n function updateVenusSupplyIndex(\n VenusMarketState memory supplyState,\n address vToken,\n ComptrollerInterface comptroller\n ) internal view {\n uint supplySpeed = comptroller.venusSupplySpeeds(vToken);\n uint blockNumber = block.number;\n uint deltaBlocks = sub_(blockNumber, uint(supplyState.block));\n if (deltaBlocks > 0 && supplySpeed > 0) {\n uint supplyTokens = VToken(vToken).totalSupply();\n uint venusAccrued = mul_(deltaBlocks, supplySpeed);\n Double memory ratio = supplyTokens > 0 ? fraction(venusAccrued, supplyTokens) : Double({ mantissa: 0 });\n Double memory index = add_(Double({ mantissa: supplyState.index }), ratio);\n supplyState.index = safe224(index.mantissa, \"new index overflows\");\n supplyState.block = safe32(blockNumber, \"block number overflows\");\n } else if (deltaBlocks > 0) {\n supplyState.block = safe32(blockNumber, \"block number overflows\");\n }\n }\n\n /**\n * @dev Queries the current borrow to calculate rewards for an account\n * @param borrowState VenusMarketState struct\n * @param vToken Address of a vToken\n * @param comptroller Address of the comptroller proxy\n */\n function updateVenusBorrowIndex(\n VenusMarketState memory borrowState,\n address vToken,\n Exp memory marketBorrowIndex,\n ComptrollerInterface comptroller\n ) internal view {\n uint borrowSpeed = comptroller.venusBorrowSpeeds(vToken);\n uint blockNumber = block.number;\n uint deltaBlocks = sub_(blockNumber, uint(borrowState.block));\n if (deltaBlocks > 0 && borrowSpeed > 0) {\n uint borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\n uint venusAccrued = mul_(deltaBlocks, borrowSpeed);\n Double memory ratio = borrowAmount > 0 ? fraction(venusAccrued, borrowAmount) : Double({ mantissa: 0 });\n Double memory index = add_(Double({ mantissa: borrowState.index }), ratio);\n borrowState.index = safe224(index.mantissa, \"new index overflows\");\n borrowState.block = safe32(blockNumber, \"block number overflows\");\n } else if (deltaBlocks > 0) {\n borrowState.block = safe32(blockNumber, \"block number overflows\");\n }\n }\n\n /**\n * @dev Calculate available rewards for an account's supply\n * @param supplyState VenusMarketState struct\n * @param vToken Address of a vToken\n * @param supplier Address of the account supplying\n * @param comptroller Address of the comptroller proxy\n * @return Undistributed earned XVS from supplies\n */\n function distributeSupplierVenus(\n VenusMarketState memory supplyState,\n address vToken,\n address supplier,\n ComptrollerInterface comptroller\n ) internal view returns (uint) {\n Double memory supplyIndex = Double({ mantissa: supplyState.index });\n Double memory supplierIndex = Double({ mantissa: comptroller.venusSupplierIndex(vToken, supplier) });\n if (supplierIndex.mantissa == 0 && supplyIndex.mantissa > 0) {\n supplierIndex.mantissa = comptroller.venusInitialIndex();\n }\n\n Double memory deltaIndex = sub_(supplyIndex, supplierIndex);\n uint supplierTokens = VToken(vToken).balanceOf(supplier);\n uint supplierDelta = mul_(supplierTokens, deltaIndex);\n return supplierDelta;\n }\n\n /**\n * @dev Calculate available rewards for an account's borrows\n * @param borrowState VenusMarketState struct\n * @param vToken Address of a vToken\n * @param borrower Address of the account borrowing\n * @param marketBorrowIndex vToken Borrow index\n * @param comptroller Address of the comptroller proxy\n * @return Undistributed earned XVS from borrows\n */\n function distributeBorrowerVenus(\n VenusMarketState memory borrowState,\n address vToken,\n address borrower,\n Exp memory marketBorrowIndex,\n ComptrollerInterface comptroller\n ) internal view returns (uint) {\n Double memory borrowIndex = Double({ mantissa: borrowState.index });\n Double memory borrowerIndex = Double({ mantissa: comptroller.venusBorrowerIndex(vToken, borrower) });\n if (borrowerIndex.mantissa > 0) {\n Double memory deltaIndex = sub_(borrowIndex, borrowerIndex);\n uint borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\n uint borrowerDelta = mul_(borrowerAmount, deltaIndex);\n return borrowerDelta;\n }\n return 0;\n }\n\n /**\n * @notice Calculate the total XVS tokens pending and accrued by a user account\n * @param holder Account to query pending XVS\n * @param comptroller Address of the comptroller\n * @return Reward object contraining the totalRewards and pending rewards for each market\n */\n function pendingRewards(\n address holder,\n ComptrollerInterface comptroller\n ) external view returns (RewardSummary memory) {\n VToken[] memory vTokens = comptroller.getAllMarkets();\n ClaimVenusLocalVariables memory vars;\n RewardSummary memory rewardSummary;\n rewardSummary.distributorAddress = address(comptroller);\n rewardSummary.rewardTokenAddress = comptroller.getXVSAddress();\n rewardSummary.totalRewards = comptroller.venusAccrued(holder);\n rewardSummary.pendingRewards = new PendingReward[](vTokens.length);\n for (uint i; i < vTokens.length; ++i) {\n (vars.borrowIndex, vars.borrowBlock) = comptroller.venusBorrowState(address(vTokens[i]));\n VenusMarketState memory borrowState = VenusMarketState({\n index: vars.borrowIndex,\n block: vars.borrowBlock\n });\n\n (vars.supplyIndex, vars.supplyBlock) = comptroller.venusSupplyState(address(vTokens[i]));\n VenusMarketState memory supplyState = VenusMarketState({\n index: vars.supplyIndex,\n block: vars.supplyBlock\n });\n\n Exp memory borrowIndex = Exp({ mantissa: vTokens[i].borrowIndex() });\n\n PendingReward memory marketReward;\n marketReward.vTokenAddress = address(vTokens[i]);\n\n updateVenusBorrowIndex(borrowState, address(vTokens[i]), borrowIndex, comptroller);\n uint256 borrowReward = distributeBorrowerVenus(\n borrowState,\n address(vTokens[i]),\n holder,\n borrowIndex,\n comptroller\n );\n\n updateVenusSupplyIndex(supplyState, address(vTokens[i]), comptroller);\n uint256 supplyReward = distributeSupplierVenus(supplyState, address(vTokens[i]), holder, comptroller);\n\n marketReward.amount = add_(borrowReward, supplyReward);\n rewardSummary.pendingRewards[i] = marketReward;\n }\n return rewardSummary;\n }\n\n // utilities\n /**\n * @notice Compares if two strings are equal\n * @param a First string to compare\n * @param b Second string to compare\n * @return Boolean depending on if the strings are equal\n */\n function compareStrings(string memory a, string memory b) internal pure returns (bool) {\n return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));\n }\n}\n" + }, + "contracts/Oracle/PriceOracle.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VToken.sol\";\n\ncontract PriceOracle {\n /// @notice Indicator that this is a PriceOracle contract (for inspection)\n bool public constant isPriceOracle = true;\n\n /**\n * @notice Get the underlying price of a vToken asset\n * @param vToken The vToken to get the underlying price of\n * @return The underlying asset price mantissa (scaled by 1e18).\n * Zero means the price is unavailable.\n */\n function getUnderlyingPrice(VToken vToken) external view returns (uint);\n}\n" + }, + "contracts/test/BEP20.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\n\n// Mock import\nimport { GovernorBravoDelegate } from \"@venusprotocol/governance-contracts/contracts/Governance/GovernorBravoDelegate.sol\";\n\ninterface BEP20Base {\n event Approval(address indexed owner, address indexed spender, uint256 value);\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n function totalSupply() external view returns (uint256);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function balanceOf(address who) external view returns (uint256);\n}\n\ncontract BEP20 is BEP20Base {\n function transfer(address to, uint256 value) external returns (bool);\n\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n\ncontract BEP20NS is BEP20Base {\n function transfer(address to, uint256 value) external;\n\n function transferFrom(address from, address to, uint256 value) external;\n}\n\n/**\n * @title Standard BEP20 token\n * @dev Implementation of the basic standard token.\n * See https://github.com/ethereum/EIPs/issues/20\n */\ncontract StandardToken is BEP20 {\n using SafeMath for uint256;\n\n string public name;\n string public symbol;\n uint8 public decimals;\n uint256 public totalSupply;\n mapping(address => mapping(address => uint256)) public allowance;\n mapping(address => uint256) public balanceOf;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public {\n totalSupply = _initialAmount;\n balanceOf[msg.sender] = _initialAmount;\n name = _tokenName;\n symbol = _tokenSymbol;\n decimals = _decimalUnits;\n }\n\n function transfer(address dst, uint256 amount) external returns (bool) {\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(address src, address dst, uint256 amount) external returns (bool) {\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount, \"Insufficient allowance\");\n balanceOf[src] = balanceOf[src].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(src, dst, amount);\n return true;\n }\n\n function approve(address _spender, uint256 amount) external returns (bool) {\n allowance[msg.sender][_spender] = amount;\n emit Approval(msg.sender, _spender, amount);\n return true;\n }\n}\n\n/**\n * @title Non-Standard BEP20 token\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\ncontract NonStandardToken is BEP20NS {\n using SafeMath for uint256;\n\n string public name;\n uint8 public decimals;\n string public symbol;\n uint256 public totalSupply;\n mapping(address => mapping(address => uint256)) public allowance;\n mapping(address => uint256) public balanceOf;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public {\n totalSupply = _initialAmount;\n balanceOf[msg.sender] = _initialAmount;\n name = _tokenName;\n symbol = _tokenSymbol;\n decimals = _decimalUnits;\n }\n\n function transfer(address dst, uint256 amount) external {\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(msg.sender, dst, amount);\n }\n\n function transferFrom(address src, address dst, uint256 amount) external {\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount, \"Insufficient allowance\");\n balanceOf[src] = balanceOf[src].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(src, dst, amount);\n }\n\n function approve(address _spender, uint256 amount) external returns (bool) {\n allowance[msg.sender][_spender] = amount;\n emit Approval(msg.sender, _spender, amount);\n return true;\n }\n}\n\ncontract BEP20Harness is StandardToken {\n // To support testing, we can specify addresses for which transferFrom should fail and return false\n mapping(address => bool) public failTransferFromAddresses;\n\n // To support testing, we allow the contract to always fail `transfer`.\n mapping(address => bool) public failTransferToAddresses;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public StandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {}\n\n function harnessSetFailTransferFromAddress(address src, bool _fail) public {\n failTransferFromAddresses[src] = _fail;\n }\n\n function harnessSetFailTransferToAddress(address dst, bool _fail) public {\n failTransferToAddresses[dst] = _fail;\n }\n\n function harnessSetBalance(address _account, uint _amount) public {\n balanceOf[_account] = _amount;\n }\n\n function transfer(address dst, uint256 amount) external returns (bool success) {\n // Added for testing purposes\n if (failTransferToAddresses[dst]) {\n return false;\n }\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success) {\n // Added for testing purposes\n if (failTransferFromAddresses[src]) {\n return false;\n }\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount, \"Insufficient allowance\");\n balanceOf[src] = balanceOf[src].sub(amount, \"Insufficient balance\");\n balanceOf[dst] = balanceOf[dst].add(amount, \"Balance overflow\");\n emit Transfer(src, dst, amount);\n return true;\n }\n}\n" + }, + "contracts/test/ComptrollerHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./ComptrollerMock.sol\";\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Comptroller/Unitroller.sol\";\n\ncontract ComptrollerHarness is ComptrollerMock {\n address internal xvsAddress;\n address internal vXVSAddress;\n uint public blockNumber;\n\n constructor() public ComptrollerMock() {}\n\n function setVenusSupplyState(address vToken, uint224 index, uint32 blockNumber_) public {\n venusSupplyState[vToken].index = index;\n venusSupplyState[vToken].block = blockNumber_;\n }\n\n function setVenusBorrowState(address vToken, uint224 index, uint32 blockNumber_) public {\n venusBorrowState[vToken].index = index;\n venusBorrowState[vToken].block = blockNumber_;\n }\n\n function setVenusAccrued(address user, uint userAccrued) public {\n venusAccrued[user] = userAccrued;\n }\n\n function setXVSAddress(address xvsAddress_) public {\n xvsAddress = xvsAddress_;\n }\n\n function setXVSVTokenAddress(address vXVSAddress_) public {\n vXVSAddress = vXVSAddress_;\n }\n\n /**\n * @notice Set the amount of XVS distributed per block\n * @param venusRate_ The amount of XVS wei per block to distribute\n */\n function harnessSetVenusRate(uint venusRate_) public {\n venusRate = venusRate_;\n }\n\n /**\n * @notice Recalculate and update XVS speeds for all XVS markets\n */\n function harnessRefreshVenusSpeeds() public {\n VToken[] memory allMarkets_ = allMarkets;\n\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets_[i];\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n updateVenusSupplyIndex(address(vToken));\n updateVenusBorrowIndex(address(vToken), borrowIndex);\n }\n\n Exp memory totalUtility = Exp({ mantissa: 0 });\n Exp[] memory utilities = new Exp[](allMarkets_.length);\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets_[i];\n if (venusSpeeds[address(vToken)] > 0) {\n Exp memory assetPrice = Exp({ mantissa: oracle.getUnderlyingPrice(vToken) });\n Exp memory utility = mul_(assetPrice, vToken.totalBorrows());\n utilities[i] = utility;\n totalUtility = add_(totalUtility, utility);\n }\n }\n\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets[i];\n uint newSpeed = totalUtility.mantissa > 0 ? mul_(venusRate, div_(utilities[i], totalUtility)) : 0;\n setVenusSpeedInternal(vToken, newSpeed, newSpeed);\n }\n }\n\n function setVenusBorrowerIndex(address vToken, address borrower, uint index) public {\n venusBorrowerIndex[vToken][borrower] = index;\n }\n\n function setVenusSupplierIndex(address vToken, address supplier, uint index) public {\n venusSupplierIndex[vToken][supplier] = index;\n }\n\n function harnessDistributeAllBorrowerVenus(\n address vToken,\n address borrower,\n uint marketBorrowIndexMantissa\n ) public {\n distributeBorrowerVenus(vToken, borrower, Exp({ mantissa: marketBorrowIndexMantissa }));\n venusAccrued[borrower] = grantXVSInternal(borrower, venusAccrued[borrower], 0, false);\n }\n\n function harnessDistributeAllSupplierVenus(address vToken, address supplier) public {\n distributeSupplierVenus(vToken, supplier);\n venusAccrued[supplier] = grantXVSInternal(supplier, venusAccrued[supplier], 0, false);\n }\n\n function harnessUpdateVenusBorrowIndex(address vToken, uint marketBorrowIndexMantissa) public {\n updateVenusBorrowIndex(vToken, Exp({ mantissa: marketBorrowIndexMantissa }));\n }\n\n function harnessUpdateVenusSupplyIndex(address vToken) public {\n updateVenusSupplyIndex(vToken);\n }\n\n function harnessDistributeBorrowerVenus(address vToken, address borrower, uint marketBorrowIndexMantissa) public {\n distributeBorrowerVenus(vToken, borrower, Exp({ mantissa: marketBorrowIndexMantissa }));\n }\n\n function harnessDistributeSupplierVenus(address vToken, address supplier) public {\n distributeSupplierVenus(vToken, supplier);\n }\n\n function harnessTransferVenus(address user, uint userAccrued, uint threshold) public returns (uint) {\n if (userAccrued > 0 && userAccrued >= threshold) {\n return grantXVSInternal(user, userAccrued, 0, false);\n }\n return userAccrued;\n }\n\n function harnessAddVenusMarkets(address[] memory vTokens) public {\n for (uint i = 0; i < vTokens.length; i++) {\n // temporarily set venusSpeed to 1 (will be fixed by `harnessRefreshVenusSpeeds`)\n setVenusSpeedInternal(VToken(vTokens[i]), 1, 1);\n }\n }\n\n function harnessSetMintedVAIs(address user, uint amount) public {\n mintedVAIs[user] = amount;\n }\n\n function harnessFastForward(uint blocks) public returns (uint) {\n blockNumber += blocks;\n return blockNumber;\n }\n\n function setBlockNumber(uint number) public {\n blockNumber = number;\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getVenusMarkets() public view returns (address[] memory) {\n uint m = allMarkets.length;\n uint n = 0;\n for (uint i = 0; i < m; i++) {\n if (venusSpeeds[address(allMarkets[i])] > 0) {\n n++;\n }\n }\n\n address[] memory venusMarkets = new address[](n);\n uint k = 0;\n for (uint i = 0; i < m; i++) {\n if (venusSpeeds[address(allMarkets[i])] > 0) {\n venusMarkets[k++] = address(allMarkets[i]);\n }\n }\n return venusMarkets;\n }\n\n function harnessSetReleaseStartBlock(uint startBlock) external {\n releaseStartBlock = startBlock;\n }\n\n function harnessAddVtoken(address vToken) external {\n markets[vToken] = Market({ isListed: true, isVenus: false, collateralFactorMantissa: 0 });\n }\n}\n\ncontract EchoTypesComptroller is UnitrollerAdminStorage {\n function stringy(string memory s) public pure returns (string memory) {\n return s;\n }\n\n function addresses(address a) public pure returns (address) {\n return a;\n }\n\n function booly(bool b) public pure returns (bool) {\n return b;\n }\n\n function listOInts(uint[] memory u) public pure returns (uint[] memory) {\n return u;\n }\n\n function reverty() public pure {\n require(false, \"gotcha sucka\");\n }\n\n function becomeBrains(address payable unitroller) public {\n Unitroller(unitroller)._acceptImplementation();\n }\n}\n" + }, + "contracts/test/ComptrollerMock.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Comptroller/Diamond/facets/MarketFacet.sol\";\nimport \"../Comptroller/Diamond/facets/PolicyFacet.sol\";\nimport \"../Comptroller/Diamond/facets/RewardFacet.sol\";\nimport \"../Comptroller/Diamond/facets/SetterFacet.sol\";\nimport \"../Comptroller/Unitroller.sol\";\n\n// This contract contains all methods of Comptroller implementation in different facets at one place for testing purpose\n// This contract does not have diamond functionality(i.e delegate call to facets methods)\ncontract ComptrollerMock is MarketFacet, PolicyFacet, RewardFacet, SetterFacet {\n constructor() public {\n admin = msg.sender;\n }\n\n function _become(Unitroller unitroller) public {\n require(msg.sender == unitroller.admin(), \"only unitroller admin can\");\n require(unitroller._acceptImplementation() == 0, \"not authorized\");\n }\n\n function _setComptrollerLens(ComptrollerLensInterface comptrollerLens_) external returns (uint) {\n ensureAdmin();\n ensureNonzeroAddress(address(comptrollerLens_));\n address oldComptrollerLens = address(comptrollerLens);\n comptrollerLens = comptrollerLens_;\n emit NewComptrollerLens(oldComptrollerLens, address(comptrollerLens));\n\n return uint(Error.NO_ERROR);\n }\n}\n" + }, + "contracts/test/ComptrollerScenario.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./ComptrollerMock.sol\";\n\ncontract ComptrollerScenario is ComptrollerMock {\n uint public blockNumber;\n address public xvsAddress;\n address public vaiAddress;\n\n constructor() public ComptrollerMock() {}\n\n function setXVSAddress(address xvsAddress_) public {\n xvsAddress = xvsAddress_;\n }\n\n // function getXVSAddress() public view returns (address) {\n // return xvsAddress;\n // }\n\n function setVAIAddress(address vaiAddress_) public {\n vaiAddress = vaiAddress_;\n }\n\n function getVAIAddress() public view returns (address) {\n return vaiAddress;\n }\n\n function membershipLength(VToken vToken) public view returns (uint) {\n return accountAssets[address(vToken)].length;\n }\n\n function fastForward(uint blocks) public returns (uint) {\n blockNumber += blocks;\n\n return blockNumber;\n }\n\n function setBlockNumber(uint number) public {\n blockNumber = number;\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getVenusMarkets() public view returns (address[] memory) {\n uint m = allMarkets.length;\n uint n = 0;\n for (uint i = 0; i < m; i++) {\n if (markets[address(allMarkets[i])].isVenus) {\n n++;\n }\n }\n\n address[] memory venusMarkets = new address[](n);\n uint k = 0;\n for (uint i = 0; i < m; i++) {\n if (markets[address(allMarkets[i])].isVenus) {\n venusMarkets[k++] = address(allMarkets[i]);\n }\n }\n return venusMarkets;\n }\n\n function unlist(VToken vToken) public {\n markets[address(vToken)].isListed = false;\n }\n\n /**\n * @notice Recalculate and update XVS speeds for all XVS markets\n */\n function refreshVenusSpeeds() public {\n VToken[] memory allMarkets_ = allMarkets;\n\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets_[i];\n Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\n updateVenusSupplyIndex(address(vToken));\n updateVenusBorrowIndex(address(vToken), borrowIndex);\n }\n\n Exp memory totalUtility = Exp({ mantissa: 0 });\n Exp[] memory utilities = new Exp[](allMarkets_.length);\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets_[i];\n if (venusSpeeds[address(vToken)] > 0) {\n Exp memory assetPrice = Exp({ mantissa: oracle.getUnderlyingPrice(vToken) });\n Exp memory utility = mul_(assetPrice, vToken.totalBorrows());\n utilities[i] = utility;\n totalUtility = add_(totalUtility, utility);\n }\n }\n\n for (uint i = 0; i < allMarkets_.length; i++) {\n VToken vToken = allMarkets[i];\n uint newSpeed = totalUtility.mantissa > 0 ? mul_(venusRate, div_(utilities[i], totalUtility)) : 0;\n setVenusSpeedInternal(vToken, newSpeed, newSpeed);\n }\n }\n}\n" + }, + "contracts/test/DiamondHarness.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Comptroller/Diamond/Diamond.sol\";\n\ncontract DiamondHarness is Diamond {\n function getFacetAddress(bytes4 sig) public view returns (address) {\n address facet = _selectorToFacetAndPosition[sig].facetAddress;\n require(facet != address(0), \"Diamond: Function does not exist\");\n return facet;\n }\n}\n" + }, + "contracts/test/EvilToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./FaucetToken.sol\";\n\n/**\n * @title The Venus Evil Test Token\n * @author Venus\n * @notice A simple test token that fails certain operations\n */\ncontract EvilToken is FaucetToken {\n bool public fail;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public FaucetToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {\n fail = true;\n }\n\n function setFail(bool _fail) external {\n fail = _fail;\n }\n\n function transfer(address dst, uint256 amount) external returns (bool) {\n if (fail) {\n return false;\n }\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount);\n balanceOf[dst] = balanceOf[dst].add(amount);\n emit Transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(address src, address dst, uint256 amount) external returns (bool) {\n if (fail) {\n return false;\n }\n balanceOf[src] = balanceOf[src].sub(amount);\n balanceOf[dst] = balanceOf[dst].add(amount);\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount);\n emit Transfer(src, dst, amount);\n return true;\n }\n}\n" + }, + "contracts/test/EvilXDelegator.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VTokenInterfaces.sol\";\n\n/**\n * @title Venus's VBep20Delegator Contract\n * @notice VTokens which wrap an EIP-20 underlying and delegate to an implementation\n * @author Venus\n */\ncontract EvilXDelegator is VTokenInterface, VBep20Interface, VDelegatorInterface {\n /**\n * @notice Construct a new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param implementation_ The address of the implementation the contract delegates to\n * @param becomeImplementationData The encoded args for becomeImplementation\n */\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint256 initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_,\n address implementation_,\n bytes memory becomeImplementationData\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(\n implementation_,\n abi.encodeWithSignature(\n \"initialize(address,address,address,uint256,string,string,uint8)\",\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_\n )\n );\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_, false, becomeImplementationData);\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\n */\n function _setImplementation(\n address implementation_,\n bool allowResign,\n bytes memory becomeImplementationData\n ) public {\n require(msg.sender == admin, \"VBep20Delegator::_setImplementation: Caller must be admin\");\n\n if (allowResign) {\n delegateToImplementation(abi.encodeWithSignature(\"_resignImplementation()\"));\n }\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n delegateToImplementation(abi.encodeWithSignature(\"_becomeImplementation(bytes)\", becomeImplementationData));\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function mint(uint256 mintAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"mint(uint256)\", mintAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function mintBehalf(address receiver, uint256 mintAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"mintBehalf(address,uint256)\", receiver, mintAmount)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function redeem(uint256 redeemTokens) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"redeem(uint256)\", redeemTokens));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function redeemUnderlying(uint256 redeemAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"redeemUnderlying(uint256)\", redeemAmount)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function borrow(uint256 borrowAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrow(uint256)\", borrowAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function repayBorrow(uint256 repayAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"repayBorrow(uint256)\", repayAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sender repays a borrow belonging to borrower\n * @param borrower the account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function repayBorrowBehalf(address borrower, uint256 repayAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"repayBorrowBehalf(address,uint256)\", borrower, repayAmount)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function liquidateBorrow(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"liquidateBorrow(address,uint256,address)\", borrower, repayAmount, vTokenCollateral)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"transfer(address,uint256)\", dst, amount));\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"transferFrom(address,address,uint256)\", src, dst, amount)\n );\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved (-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"approve(address,uint256)\", spender, amount)\n );\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return The number of tokens allowed to be spent (-1 means infinite)\n */\n function allowance(address owner, address spender) external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"allowance(address,address)\", owner, spender)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Get the token balance of the `owner`\n * @param owner The address of the account to query\n * @return The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"balanceOf(address)\", owner));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Get the underlying balance of the `owner`\n * @dev This also accrues interest in a transaction\n * @param owner The address of the account to query\n * @return The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"balanceOfUnderlying(address)\", owner));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\n * @param account Address of the account to snapshot\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\n */\n function getAccountSnapshot(address account) external view returns (uint256, uint256, uint256, uint256) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"getAccountSnapshot(address)\", account)\n );\n return abi.decode(data, (uint256, uint256, uint256, uint256));\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"borrowRatePerBlock()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this vToken\n * @return The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"supplyRatePerBlock()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return The total borrows with interest\n */\n function totalBorrowsCurrent() external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"totalBorrowsCurrent()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\n * @param account The address whose balance should be calculated after updating borrowIndex\n * @return The calculated balance\n */\n function borrowBalanceCurrent(address account) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrowBalanceCurrent(address)\", account));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Return the borrow balance of account based on stored data\n * @param account The address whose balance should be calculated\n * @return The calculated balance\n */\n function borrowBalanceStored(address account) public view returns (uint256) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"borrowBalanceStored(address)\", account)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"exchangeRateCurrent()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Calculates the exchange rate from the underlying to the VToken\n * @dev This function does not accrue interest before calculating the exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() public view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"exchangeRateStored()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return The quantity of underlying asset owned by this contract\n */\n function getCash() external view returns (uint256) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"getCash()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Applies accrued interest to total borrows and reserves.\n * @dev This calculates interest accrued from the last checkpointed block\n * up to the current block and writes new checkpoint to storage.\n */\n function accrueInterest() public returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"accrueInterest()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Transfers collateral tokens (this market) to the liquidator.\n * @dev Will fail unless called by another vToken during the process of liquidation.\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\n * @param liquidator The account receiving seized collateral\n * @param borrower The account having collateral seized\n * @param seizeTokens The number of vTokens to seize\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function seize(address liquidator, address borrower, uint256 seizeTokens) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"seize(address,address,uint256)\", liquidator, borrower, seizeTokens)\n );\n return abi.decode(data, (uint256));\n }\n\n /*** Admin Functions ***/\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setPendingAdmin(address)\", newPendingAdmin)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Sets a new comptroller for the market\n * @dev Admin function to set a new comptroller\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setComptroller(address)\", newComptroller)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh\n * @dev Admin function to accrue interest and set a new reserve factor\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setReserveFactor(uint256 newReserveFactorMantissa) external returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setReserveFactor(uint256)\", newReserveFactorMantissa)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_acceptAdmin()\"));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrues interest and adds reserves by transferring from admin\n * @param addAmount Amount of reserves to add\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _addReserves(uint256 addAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_addReserves(uint256)\", addAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to admin\n * @param reduceAmount Amount of reduction to reserves\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _reduceReserves(uint256 reduceAmount) external returns (uint256) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_reduceReserves(uint256)\", reduceAmount));\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\n * @dev Admin function to accrue interest and update the interest rate model\n * @param newInterestRateModel the new interest rate model to use\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint256) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setInterestRateModel(address)\", newInterestRateModel)\n );\n return abi.decode(data, (uint256));\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n\n /**\n * @notice Delegates execution to the implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateToImplementation(bytes memory data) public returns (bytes memory) {\n return delegateTo(implementation, data);\n }\n\n /**\n * @notice Delegates execution to an implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * There are an additional 2 prefix uints from the wrapper returndata, which we ignore since we make an extra hop.\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateToViewImplementation(bytes memory data) public view returns (bytes memory) {\n (bool success, bytes memory returnData) = address(this).staticcall(\n abi.encodeWithSignature(\"delegateToImplementation(bytes)\", data)\n );\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return abi.decode(returnData, (bytes));\n }\n\n /**\n * @notice Delegates execution to an implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n */\n function() external payable {\n require(msg.value == 0, \"VBep20Delegator:fallback: cannot send value to fallback\");\n\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/test/EvilXToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VBep20Immutable.sol\";\nimport \"../Tokens/VTokens/VBep20Delegator.sol\";\nimport \"../Tokens/VTokens/VBep20Delegate.sol\";\nimport \"./ComptrollerScenario.sol\";\nimport \"../Comptroller/ComptrollerInterface.sol\";\n\ncontract VBep20Scenario is VBep20Immutable {\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n )\n public\n VBep20Immutable(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_\n )\n {}\n\n function setTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function setTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function getBlockNumber() internal view returns (uint) {\n ComptrollerScenario comptrollerScenario = ComptrollerScenario(address(comptroller));\n return comptrollerScenario.blockNumber();\n }\n}\n\n// doTransferOut method of this token supposed to be compromised and contians malicious code which\n// can be used by attacker to compromise the protocol working.\ncontract EvilXToken is VBep20Delegate {\n event Log(string x, address y);\n event Log(string x, uint y);\n event LogLiquidity(uint liquidity);\n\n uint internal blockNumber = 100000;\n uint internal harnessExchangeRate;\n bool internal harnessExchangeRateStored;\n\n address public comptrollerAddress;\n\n mapping(address => bool) public failTransferToAddresses;\n\n function setComptrollerAddress(address _comptrollerAddress) external {\n comptrollerAddress = _comptrollerAddress;\n }\n\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\n if (harnessExchangeRateStored) {\n return (MathError.NO_ERROR, harnessExchangeRate);\n }\n return super.exchangeRateStoredInternal();\n }\n\n function doTransferOut(address payable to, uint amount) internal {\n require(failTransferToAddresses[to] == false, \"TOKEN_TRANSFER_OUT_FAILED\");\n super.doTransferOut(to, amount);\n\n // Checking the Liquidity of the user after the tranfer.\n // solhint-disable-next-line no-unused-vars\n (uint errorCode, uint liquidity, uint shortfall) = ComptrollerInterface(comptrollerAddress).getAccountLiquidity(\n msg.sender\n );\n emit LogLiquidity(liquidity);\n return;\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getBorrowRateMaxMantissa() public pure returns (uint) {\n return borrowRateMaxMantissa;\n }\n\n function harnessSetBlockNumber(uint newBlockNumber) public {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetAccrualBlockNumber(uint _accrualblockNumber) public {\n accrualBlockNumber = _accrualblockNumber;\n }\n\n function harnessSetTotalSupply(uint totalSupply_) public {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function harnessIncrementTotalBorrows(uint addtlBorrow_) public {\n totalBorrows = totalBorrows + addtlBorrow_;\n }\n\n function harnessSetTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(uint totalSupply_, uint totalBorrows_, uint totalReserves_) public {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint exchangeRate) public {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address _to, bool _fail) public {\n failTransferToAddresses[_to] = _fail;\n }\n\n function harnessMintFresh(address account, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintFresh(account, mintAmount);\n return err;\n }\n\n function harnessMintBehalfFresh(address payer, address receiver, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintBehalfFresh(payer, receiver, mintAmount);\n return err;\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint vTokenAmount,\n uint underlyingAmount\n ) public returns (uint) {\n return super.redeemFresh(account, account, vTokenAmount, underlyingAmount);\n }\n\n function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function harnessSetAccountBorrows(address account, uint principal, uint interestIndex) public {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint borrowIndex_) public {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint borrowAmount) public returns (uint) {\n return borrowFresh(account, account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(address payer, address account, uint repayAmount) public returns (uint) {\n (uint err, ) = repayBorrowFresh(payer, account, repayAmount);\n return err;\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VToken vTokenCollateral\n ) public returns (uint) {\n (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n function harnessReduceReservesFresh(uint amount) public returns (uint) {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint newReserveFactorMantissa) public returns (uint) {\n return _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) public returns (uint) {\n return _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallBorrowAllowed(uint amount) public returns (uint) {\n return comptroller.borrowAllowed(address(this), msg.sender, amount);\n }\n}\n" + }, + "contracts/test/Fauceteer.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/EIP20NonStandardInterface.sol\";\n\n/**\n * @title Fauceteer\n * @author Venus\n * @notice First computer program to be part of The Giving Pledge\n */\ncontract Fauceteer {\n /**\n * @notice Drips some tokens to caller\n * @dev We send 0.01% of our tokens to the caller. Over time, the amount will tend toward and eventually reach zero.\n * @param token The token to drip. Note: if we have no balance in this token, function will revert.\n */\n function drip(EIP20NonStandardInterface token) public {\n uint tokenBalance = token.balanceOf(address(this));\n require(tokenBalance > 0, \"Fauceteer is empty\");\n token.transfer(msg.sender, tokenBalance / 10000); // 0.01%\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a compliant BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n\n require(success, \"Transfer returned false.\");\n }\n}\n" + }, + "contracts/test/FaucetToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./BEP20.sol\";\n\n/**\n * @title The Venus Faucet Test Token\n * @author Venus\n * @notice A simple test token that lets anyone get more of it.\n */\ncontract FaucetToken is StandardToken {\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public StandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {}\n\n function allocateTo(address _owner, uint256 value) public {\n balanceOf[_owner] += value;\n totalSupply += value;\n emit Transfer(address(this), _owner, value);\n }\n}\n\n/**\n * @title The Venus Faucet Test Token (non-standard)\n * @author Venus\n * @notice A simple test token that lets anyone get more of it.\n */\ncontract FaucetNonStandardToken is NonStandardToken {\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol\n ) public NonStandardToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {}\n\n function allocateTo(address _owner, uint256 value) public {\n balanceOf[_owner] += value;\n totalSupply += value;\n emit Transfer(address(this), _owner, value);\n }\n}\n\n/**\n * @title The Venus Faucet Re-Entrant Test Token\n * @author Venus\n * @notice A test token that is malicious and tries to re-enter callers\n */\ncontract FaucetTokenReEntrantHarness {\n using SafeMath for uint256;\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n string public name;\n string public symbol;\n uint8 public decimals;\n uint256 internal totalSupply_;\n mapping(address => mapping(address => uint256)) internal allowance_;\n mapping(address => uint256) internal balanceOf_;\n\n bytes public reEntryCallData;\n string public reEntryFun;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol,\n bytes memory _reEntryCallData,\n string memory _reEntryFun\n ) public {\n totalSupply_ = _initialAmount;\n balanceOf_[msg.sender] = _initialAmount;\n name = _tokenName;\n symbol = _tokenSymbol;\n decimals = _decimalUnits;\n reEntryCallData = _reEntryCallData;\n reEntryFun = _reEntryFun;\n }\n\n modifier reEnter(string memory funName) {\n string memory _reEntryFun = reEntryFun;\n if (compareStrings(_reEntryFun, funName)) {\n reEntryFun = \"\"; // Clear re-entry fun\n (bool success, bytes memory returndata) = msg.sender.call(reEntryCallData);\n assembly {\n if eq(success, 0) {\n revert(add(returndata, 0x20), returndatasize())\n }\n }\n }\n\n _;\n }\n\n function compareStrings(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)));\n }\n\n function allocateTo(address _owner, uint256 value) public {\n balanceOf_[_owner] += value;\n totalSupply_ += value;\n emit Transfer(address(this), _owner, value);\n }\n\n function totalSupply() public reEnter(\"totalSupply\") returns (uint256) {\n return totalSupply_;\n }\n\n function allowance(address owner, address spender) public reEnter(\"allowance\") returns (uint256 remaining) {\n return allowance_[owner][spender];\n }\n\n function approve(address spender, uint256 amount) public reEnter(\"approve\") returns (bool success) {\n _approve(msg.sender, spender, amount);\n return true;\n }\n\n function balanceOf(address owner) public reEnter(\"balanceOf\") returns (uint256 balance) {\n return balanceOf_[owner];\n }\n\n function transfer(address dst, uint256 amount) public reEnter(\"transfer\") returns (bool success) {\n _transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) public reEnter(\"transferFrom\") returns (bool success) {\n _transfer(src, dst, amount);\n _approve(src, msg.sender, allowance_[src][msg.sender].sub(amount));\n return true;\n }\n\n function _approve(address owner, address spender, uint256 amount) internal {\n require(spender != address(0), \"sender should be valid address\");\n require(owner != address(0), \"owner should be valid address\");\n allowance_[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n function _transfer(address src, address dst, uint256 amount) internal {\n require(dst != address(0), \"dst should be valid address\");\n balanceOf_[src] = balanceOf_[src].sub(amount);\n balanceOf_[dst] = balanceOf_[dst].add(amount);\n emit Transfer(src, dst, amount);\n }\n}\n" + }, + "contracts/test/FeeToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./FaucetToken.sol\";\n\n/**\n * @title Fee Token\n * @author Venus\n * @notice A simple test token that charges fees on transfer. Used to mock USDT.\n */\ncontract FeeToken is FaucetToken {\n uint public basisPointFee;\n address public owner;\n\n constructor(\n uint256 _initialAmount,\n string memory _tokenName,\n uint8 _decimalUnits,\n string memory _tokenSymbol,\n uint _basisPointFee,\n address _owner\n ) public FaucetToken(_initialAmount, _tokenName, _decimalUnits, _tokenSymbol) {\n basisPointFee = _basisPointFee;\n owner = _owner;\n }\n\n function transfer(address dst, uint amount) public returns (bool) {\n uint fee = amount.mul(basisPointFee).div(10000);\n uint net = amount.sub(fee);\n balanceOf[owner] = balanceOf[owner].add(fee);\n balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount);\n balanceOf[dst] = balanceOf[dst].add(net);\n emit Transfer(msg.sender, dst, amount);\n return true;\n }\n\n function transferFrom(address src, address dst, uint amount) public returns (bool) {\n uint fee = amount.mul(basisPointFee).div(10000);\n uint net = amount.sub(fee);\n balanceOf[owner] = balanceOf[owner].add(fee);\n balanceOf[src] = balanceOf[src].sub(amount);\n balanceOf[dst] = balanceOf[dst].add(net);\n allowance[src][msg.sender] = allowance[src][msg.sender].sub(amount);\n emit Transfer(src, dst, amount);\n return true;\n }\n}\n" + }, + "contracts/test/FixedPriceOracle.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Oracle/PriceOracle.sol\";\n\ncontract FixedPriceOracle is PriceOracle {\n uint public price;\n\n constructor(uint _price) public {\n price = _price;\n }\n\n function getUnderlyingPrice(VToken vToken) public view returns (uint) {\n vToken;\n return price;\n }\n\n function assetPrices(address asset) public view returns (uint) {\n asset;\n return price;\n }\n}\n" + }, + "contracts/test/InterestRateModelHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../InterestRateModels/InterestRateModel.sol\";\n\n/**\n * @title An Interest Rate Model for tests that can be instructed to return a failure instead of doing a calculation\n * @author Venus\n */\ncontract InterestRateModelHarness is InterestRateModel {\n uint public constant opaqueBorrowFailureCode = 20;\n bool public failBorrowRate;\n uint public borrowRate;\n\n constructor(uint borrowRate_) public {\n borrowRate = borrowRate_;\n }\n\n function setFailBorrowRate(bool failBorrowRate_) public {\n failBorrowRate = failBorrowRate_;\n }\n\n function setBorrowRate(uint borrowRate_) public {\n borrowRate = borrowRate_;\n }\n\n function getBorrowRate(uint _cash, uint _borrows, uint _reserves) public view returns (uint) {\n _cash; // unused\n _borrows; // unused\n _reserves; // unused\n require(!failBorrowRate, \"INTEREST_RATE_MODEL_ERROR\");\n return borrowRate;\n }\n\n function getSupplyRate(\n uint _cash,\n uint _borrows,\n uint _reserves,\n uint _reserveFactor\n ) external view returns (uint) {\n _cash; // unused\n _borrows; // unused\n _reserves; // unused\n return borrowRate * (1 - _reserveFactor);\n }\n}\n" + }, + "contracts/test/MockDeflationaryToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\n\ncontract DeflatingERC20 {\n using SafeMath for uint;\n\n string public constant name = \"Deflating Test Token\";\n string public constant symbol = \"DTT\";\n uint8 public constant decimals = 18;\n uint public totalSupply;\n mapping(address => uint) public balanceOf;\n mapping(address => mapping(address => uint)) public allowance;\n\n bytes32 public DOMAIN_SEPARATOR;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint) public nonces;\n\n event Approval(address indexed owner, address indexed spender, uint value);\n event Transfer(address indexed from, address indexed to, uint value);\n\n constructor(uint _totalSupply) public {\n uint chainId;\n assembly {\n chainId := chainid()\n }\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n _mint(msg.sender, _totalSupply);\n }\n\n function _mint(address to, uint value) internal {\n totalSupply = totalSupply.add(value);\n balanceOf[to] = balanceOf[to].add(value);\n emit Transfer(address(0), to, value);\n }\n\n function _burn(address from, uint value) internal {\n balanceOf[from] = balanceOf[from].sub(value);\n totalSupply = totalSupply.sub(value);\n emit Transfer(from, address(0), value);\n }\n\n function _approve(address owner, address spender, uint value) private {\n allowance[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _transfer(address from, address to, uint value) private {\n uint burnAmount = value / 100;\n _burn(from, burnAmount);\n uint transferAmount = value.sub(burnAmount);\n balanceOf[from] = balanceOf[from].sub(transferAmount);\n balanceOf[to] = balanceOf[to].add(transferAmount);\n emit Transfer(from, to, transferAmount);\n }\n\n function approve(address spender, uint value) external returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transfer(address to, uint value) external returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint value) external returns (bool) {\n if (allowance[from][msg.sender] != uint(-1)) {\n allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);\n }\n _transfer(from, to, value);\n return true;\n }\n\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n require(deadline >= block.timestamp, \"EXPIRED\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNATURE\");\n _approve(owner, spender, value);\n }\n}\n" + }, + "contracts/test/MockVBNB.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VToken.sol\";\n\n/**\n * @title Venus's vBNB Contract\n * @notice vToken which wraps BNB\n * @author Venus\n */\ncontract MockVBNB is VToken {\n /**\n * @notice Construct a new vBNB money market\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n */\n constructor(\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_);\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n\n /**\n * @notice Send BNB to VBNB to mint\n */\n function() external payable {\n (uint err, ) = mintInternal(msg.value);\n requireNoError(err, \"mint failed\");\n }\n\n /*** User Interface ***/\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Reverts upon any failure\n */\n // @custom:event Emits Transfer event\n // @custom:event Emits Mint event\n function mint() external payable {\n (uint err, ) = mintInternal(msg.value);\n requireNoError(err, \"mint failed\");\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeem(uint redeemTokens) external returns (uint) {\n return redeemInternal(msg.sender, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n return redeemUnderlyingInternal(msg.sender, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Borrow event on success\n function borrow(uint borrowAmount) external returns (uint) {\n return borrowInternal(msg.sender, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @dev Reverts upon any failure\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrow() external payable {\n (uint err, ) = repayBorrowInternal(msg.value);\n requireNoError(err, \"repayBorrow failed\");\n }\n\n /**\n * @notice Sender repays a borrow belonging to borrower\n * @dev Reverts upon any failure\n * @param borrower The account with the debt being payed off\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrowBehalf(address borrower) external payable {\n (uint err, ) = repayBorrowBehalfInternal(borrower, msg.value);\n requireNoError(err, \"repayBorrowBehalf failed\");\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @dev Reverts upon any failure\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n */\n // @custom:event Emit LiquidateBorrow event on success\n function liquidateBorrow(address borrower, VToken vTokenCollateral) external payable {\n (uint err, ) = liquidateBorrowInternal(borrower, msg.value, vTokenCollateral);\n requireNoError(err, \"liquidateBorrow failed\");\n }\n\n function setTotalReserves(uint totalReserves_) external payable {\n totalReserves = totalReserves_;\n }\n\n /*** Safe Token ***/\n\n /**\n * @notice Perform the actual transfer in, which is a no-op\n * @param from Address sending the BNB\n * @param amount Amount of BNB being sent\n * @return The actual amount of BNB transferred\n */\n function doTransferIn(address from, uint amount) internal returns (uint) {\n // Sanity checks\n require(msg.sender == from, \"sender mismatch\");\n require(msg.value == amount, \"value mismatch\");\n return amount;\n }\n\n function doTransferOut(address payable to, uint amount) internal {\n /* Send the BNB, with minimal gas and revert on failure */\n to.transfer(amount);\n }\n\n /**\n * @notice Gets balance of this contract in terms of BNB, before this message\n * @dev This excludes the value of the current message, if any\n * @return The quantity of BNB owned by this contract\n */\n function getCashPrior() internal view returns (uint) {\n (MathError err, uint startingBalance) = subUInt(address(this).balance, msg.value);\n require(err == MathError.NO_ERROR, \"cash prior math error\");\n return startingBalance;\n }\n\n function requireNoError(uint errCode, string memory message) internal pure {\n if (errCode == uint(Error.NO_ERROR)) {\n return;\n }\n\n bytes memory fullMessage = new bytes(bytes(message).length + 5);\n uint i;\n\n for (i = 0; i < bytes(message).length; i++) {\n fullMessage[i] = bytes(message)[i];\n }\n\n fullMessage[i + 0] = bytes1(uint8(32));\n fullMessage[i + 1] = bytes1(uint8(40));\n fullMessage[i + 2] = bytes1(uint8(48 + (errCode / 10)));\n fullMessage[i + 3] = bytes1(uint8(48 + (errCode % 10)));\n fullMessage[i + 4] = bytes1(uint8(41));\n\n require(errCode == uint(Error.NO_ERROR), string(fullMessage));\n }\n\n /**\n * @dev Function to simply retrieve block number\n * This exists mainly for inheriting test contracts to stub this result.\n */\n function getBlockNumber() internal view returns (uint) {\n return block.number;\n }\n\n /**\n * @notice Reduces reserves by transferring to admin\n * @dev Requires fresh interest accrual\n * @param reduceAmount Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\n // totalReserves - reduceAmount\n uint totalReservesNew;\n\n // Check caller is admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.REDUCE_RESERVES_ADMIN_CHECK);\n }\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != getBlockNumber()) {\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\n }\n\n // Fail gracefully if protocol has insufficient underlying cash\n if (getCashPrior() < reduceAmount) {\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\n }\n\n // Check reduceAmount ≤ reserves[n] (totalReserves)\n if (reduceAmount > totalReserves) {\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n totalReservesNew = totalReserves - reduceAmount;\n\n // Store reserves[n+1] = reserves[n] - reduceAmount\n totalReserves = totalReservesNew;\n\n // // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\n doTransferOut(admin, reduceAmount);\n\n emit ReservesReduced(admin, reduceAmount, totalReservesNew);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to admin\n * @param reduceAmount Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits ReservesReduced event\n function _reduceReserves(uint reduceAmount) external nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\n }\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\n return _reduceReservesFresh(reduceAmount);\n }\n\n /**\n * @notice Applies accrued interest to total borrows and reserves\n * @dev This calculates interest accrued from the last checkpointed block\n * up to the current block and writes new checkpoint to storage.\n */\n // @custom:event Emits AccrueInterest event\n function accrueInterest() public returns (uint) {\n /* Remember the initial block number */\n uint currentBlockNumber = getBlockNumber();\n uint accrualBlockNumberPrior = accrualBlockNumber;\n\n /* Short-circuit accumulating 0 interest */\n if (accrualBlockNumberPrior == currentBlockNumber) {\n return uint(Error.NO_ERROR);\n }\n\n /* Read the previous values out of storage */\n uint cashPrior = getCashPrior();\n uint borrowsPrior = totalBorrows;\n uint reservesPrior = totalReserves;\n uint borrowIndexPrior = borrowIndex;\n\n /* Calculate the current borrow interest rate */\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\n require(borrowRateMantissa <= borrowRateMaxMantissa, \"borrow rate is absurdly high\");\n\n /* Calculate the number of blocks elapsed since the last accrual */\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\n require(mathErr == MathError.NO_ERROR, \"could not calculate block delta\");\n\n /*\n * Calculate the interest accumulated into borrows and reserves and the new index:\n * simpleInterestFactor = borrowRate * blockDelta\n * interestAccumulated = simpleInterestFactor * totalBorrows\n * totalBorrowsNew = interestAccumulated + totalBorrows\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\n */\n\n Exp memory simpleInterestFactor;\n uint interestAccumulated;\n uint totalBorrowsNew;\n uint totalReservesNew;\n uint borrowIndexNew;\n\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\n Exp({ mantissa: reserveFactorMantissa }),\n interestAccumulated,\n reservesPrior\n );\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the previously calculated values into storage */\n accrualBlockNumber = currentBlockNumber;\n borrowIndex = borrowIndexNew;\n totalBorrows = totalBorrowsNew;\n totalReserves = totalReservesNew;\n\n /* We emit an AccrueInterest event */\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\n\n return uint(Error.NO_ERROR);\n }\n}\n" + }, + "contracts/test/SimplePriceOracle.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Oracle/PriceOracle.sol\";\nimport \"../Tokens/VTokens/VBep20.sol\";\n\ncontract SimplePriceOracle is PriceOracle {\n mapping(address => uint) internal prices;\n event PricePosted(address asset, uint previousPriceMantissa, uint requestedPriceMantissa, uint newPriceMantissa);\n\n function getUnderlyingPrice(VToken vToken) public view returns (uint) {\n if (compareStrings(vToken.symbol(), \"vBNB\")) {\n return 1e18;\n } else if (compareStrings(vToken.symbol(), \"VAI\")) {\n return prices[address(vToken)];\n } else {\n return prices[address(VBep20(address(vToken)).underlying())];\n }\n }\n\n function setUnderlyingPrice(VToken vToken, uint underlyingPriceMantissa) public {\n address asset = address(VBep20(address(vToken)).underlying());\n emit PricePosted(asset, prices[asset], underlyingPriceMantissa, underlyingPriceMantissa);\n prices[asset] = underlyingPriceMantissa;\n }\n\n function setDirectPrice(address asset, uint price) public {\n emit PricePosted(asset, prices[asset], price, price);\n prices[asset] = price;\n }\n\n // v1 price oracle interface for use as backing of proxy\n function assetPrices(address asset) external view returns (uint) {\n return prices[asset];\n }\n\n function compareStrings(string memory a, string memory b) internal pure returns (bool) {\n return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));\n }\n}\n" + }, + "contracts/test/VAIControllerHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VAI/VAIController.sol\";\n\ncontract VAIControllerHarness is VAIController {\n uint public blockNumber;\n uint public blocksPerYear;\n\n constructor() public VAIController() {\n admin = msg.sender;\n }\n\n function setVenusVAIState(uint224 index, uint32 blockNumber_) public {\n venusVAIState.index = index;\n venusVAIState.block = blockNumber_;\n }\n\n function setVAIAddress(address vaiAddress_) public {\n vai = vaiAddress_;\n }\n\n function getVAIAddress() public view returns (address) {\n return vai;\n }\n\n function harnessRepayVAIFresh(address payer, address account, uint repayAmount) public returns (uint) {\n (uint err, ) = repayVAIFresh(payer, account, repayAmount);\n return err;\n }\n\n function harnessLiquidateVAIFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VToken vTokenCollateral\n ) public returns (uint) {\n (uint err, ) = liquidateVAIFresh(liquidator, borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n function harnessFastForward(uint blocks) public returns (uint) {\n blockNumber += blocks;\n return blockNumber;\n }\n\n function harnessSetBlockNumber(uint newBlockNumber) public {\n blockNumber = newBlockNumber;\n }\n\n function setBlockNumber(uint number) public {\n blockNumber = number;\n }\n\n function setBlocksPerYear(uint number) public {\n blocksPerYear = number;\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getBlocksPerYear() public view returns (uint) {\n return blocksPerYear;\n }\n}\n" + }, + "contracts/test/VAIHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VAI/VAI.sol\";\n\ncontract VAIScenario is VAI {\n uint internal blockNumber = 100000;\n\n constructor(uint chainId) public VAI(chainId) {}\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n function harnessSetTotalSupply(uint _totalSupply) public {\n totalSupply = _totalSupply;\n }\n\n function harnessIncrementTotalSupply(uint addtlSupply_) public {\n totalSupply = totalSupply + addtlSupply_;\n }\n\n function harnessSetBalanceOf(address account, uint _amount) public {\n balanceOf[account] = _amount;\n }\n\n function allocateTo(address _owner, uint256 value) public {\n balanceOf[_owner] += value;\n totalSupply += value;\n emit Transfer(address(this), _owner, value);\n }\n}\n" + }, + "contracts/test/VBep20Harness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VBep20Immutable.sol\";\nimport \"../Tokens/VTokens/VBep20Delegator.sol\";\nimport \"../Tokens/VTokens/VBep20Delegate.sol\";\nimport \"./ComptrollerScenario.sol\";\n\ncontract VBep20Harness is VBep20Immutable {\n uint internal blockNumber = 100000;\n uint internal harnessExchangeRate;\n bool internal harnessExchangeRateStored;\n\n mapping(address => bool) public failTransferToAddresses;\n\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n )\n public\n VBep20Immutable(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_\n )\n {}\n\n function doTransferOut(address payable to, uint amount) internal {\n require(failTransferToAddresses[to] == false, \"TOKEN_TRANSFER_OUT_FAILED\");\n return super.doTransferOut(to, amount);\n }\n\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\n if (harnessExchangeRateStored) {\n return (MathError.NO_ERROR, harnessExchangeRate);\n }\n return super.exchangeRateStoredInternal();\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getBorrowRateMaxMantissa() public pure returns (uint) {\n return borrowRateMaxMantissa;\n }\n\n function harnessSetAccrualBlockNumber(uint _accrualblockNumber) public {\n accrualBlockNumber = _accrualblockNumber;\n }\n\n function harnessSetBlockNumber(uint newBlockNumber) public {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetTotalSupply(uint totalSupply_) public {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function harnessSetTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(uint totalSupply_, uint totalBorrows_, uint totalReserves_) public {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint exchangeRate) public {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address _to, bool _fail) public {\n failTransferToAddresses[_to] = _fail;\n }\n\n function harnessMintFresh(address account, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintFresh(account, mintAmount);\n return err;\n }\n\n function harnessMintBehalfFresh(address payer, address receiver, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintBehalfFresh(payer, receiver, mintAmount);\n return err;\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint vTokenAmount,\n uint underlyingAmount\n ) public returns (uint) {\n return super.redeemFresh(account, account, vTokenAmount, underlyingAmount);\n }\n\n function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function harnessSetAccountBorrows(address account, uint principal, uint interestIndex) public {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint borrowIndex_) public {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint borrowAmount) public returns (uint) {\n return borrowFresh(account, account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(address payer, address account, uint repayAmount) public returns (uint) {\n (uint err, ) = repayBorrowFresh(payer, account, repayAmount);\n return err;\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VToken vTokenCollateral\n ) public returns (uint) {\n (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n function harnessReduceReservesFresh(uint amount) public returns (uint) {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint newReserveFactorMantissa) public returns (uint) {\n return _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) public returns (uint) {\n return _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallBorrowAllowed(uint amount) public returns (uint) {\n return comptroller.borrowAllowed(address(this), msg.sender, amount);\n }\n}\n\ncontract VBep20Scenario is VBep20Immutable {\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n )\n public\n VBep20Immutable(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_\n )\n {}\n\n function setTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function setTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function getBlockNumber() internal view returns (uint) {\n ComptrollerScenario comptrollerScenario = ComptrollerScenario(address(comptroller));\n return comptrollerScenario.blockNumber();\n }\n}\n\ncontract VEvil is VBep20Scenario {\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n )\n public\n VBep20Scenario(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_\n )\n {}\n\n function evilSeize(VToken treasure, address liquidator, address borrower, uint seizeTokens) public returns (uint) {\n return treasure.seize(liquidator, borrower, seizeTokens);\n }\n}\n\ncontract VBep20DelegatorScenario is VBep20Delegator {\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_,\n address implementation_,\n bytes memory becomeImplementationData\n )\n public\n VBep20Delegator(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_,\n admin_,\n implementation_,\n becomeImplementationData\n )\n {}\n\n function setTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function setTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n}\n\ncontract VBep20DelegateHarness is VBep20Delegate {\n event Log(string x, address y);\n event Log(string x, uint y);\n\n uint internal blockNumber = 100000;\n uint internal harnessExchangeRate;\n bool internal harnessExchangeRateStored;\n\n mapping(address => bool) public failTransferToAddresses;\n\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\n if (harnessExchangeRateStored) {\n return (MathError.NO_ERROR, harnessExchangeRate);\n }\n return super.exchangeRateStoredInternal();\n }\n\n function doTransferOut(address payable to, uint amount) internal {\n require(failTransferToAddresses[to] == false, \"TOKEN_TRANSFER_OUT_FAILED\");\n return super.doTransferOut(to, amount);\n }\n\n function getBlockNumber() internal view returns (uint) {\n return blockNumber;\n }\n\n function getBorrowRateMaxMantissa() public pure returns (uint) {\n return borrowRateMaxMantissa;\n }\n\n function harnessSetBlockNumber(uint newBlockNumber) public {\n blockNumber = newBlockNumber;\n }\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n function harnessSetBalance(address account, uint amount) external {\n accountTokens[account] = amount;\n }\n\n function harnessSetAccrualBlockNumber(uint _accrualblockNumber) public {\n accrualBlockNumber = _accrualblockNumber;\n }\n\n function harnessSetTotalSupply(uint totalSupply_) public {\n totalSupply = totalSupply_;\n }\n\n function harnessSetTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function harnessIncrementTotalBorrows(uint addtlBorrow_) public {\n totalBorrows = totalBorrows + addtlBorrow_;\n }\n\n function harnessSetTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function harnessExchangeRateDetails(uint totalSupply_, uint totalBorrows_, uint totalReserves_) public {\n totalSupply = totalSupply_;\n totalBorrows = totalBorrows_;\n totalReserves = totalReserves_;\n }\n\n function harnessSetExchangeRate(uint exchangeRate) public {\n harnessExchangeRate = exchangeRate;\n harnessExchangeRateStored = true;\n }\n\n function harnessSetFailTransferToAddress(address _to, bool _fail) public {\n failTransferToAddresses[_to] = _fail;\n }\n\n function harnessMintFresh(address account, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintFresh(account, mintAmount);\n return err;\n }\n\n function harnessMintBehalfFresh(address payer, address receiver, uint mintAmount) public returns (uint) {\n (uint err, ) = super.mintBehalfFresh(payer, receiver, mintAmount);\n return err;\n }\n\n function harnessRedeemFresh(\n address payable account,\n uint vTokenAmount,\n uint underlyingAmount\n ) public returns (uint) {\n return super.redeemFresh(account, account, vTokenAmount, underlyingAmount);\n }\n\n function harnessAccountBorrows(address account) public view returns (uint principal, uint interestIndex) {\n BorrowSnapshot memory snapshot = accountBorrows[account];\n return (snapshot.principal, snapshot.interestIndex);\n }\n\n function harnessSetAccountBorrows(address account, uint principal, uint interestIndex) public {\n accountBorrows[account] = BorrowSnapshot({ principal: principal, interestIndex: interestIndex });\n }\n\n function harnessSetBorrowIndex(uint borrowIndex_) public {\n borrowIndex = borrowIndex_;\n }\n\n function harnessBorrowFresh(address payable account, uint borrowAmount) public returns (uint) {\n return borrowFresh(account, account, borrowAmount);\n }\n\n function harnessRepayBorrowFresh(address payer, address account, uint repayAmount) public returns (uint) {\n (uint err, ) = repayBorrowFresh(payer, account, repayAmount);\n return err;\n }\n\n function harnessLiquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VToken vTokenCollateral\n ) public returns (uint) {\n (uint err, ) = liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n function harnessReduceReservesFresh(uint amount) public returns (uint) {\n return _reduceReservesFresh(amount);\n }\n\n function harnessSetReserveFactorFresh(uint newReserveFactorMantissa) public returns (uint) {\n return _setReserveFactorFresh(newReserveFactorMantissa);\n }\n\n function harnessSetInterestRateModelFresh(InterestRateModel newInterestRateModel) public returns (uint) {\n return _setInterestRateModelFresh(newInterestRateModel);\n }\n\n function harnessSetInterestRateModel(address newInterestRateModelAddress) public {\n interestRateModel = InterestRateModel(newInterestRateModelAddress);\n }\n\n function harnessCallBorrowAllowed(uint amount) public returns (uint) {\n return comptroller.borrowAllowed(address(this), msg.sender, amount);\n }\n}\n\ncontract VBep20DelegateScenario is VBep20Delegate {\n constructor() public {}\n\n function setTotalBorrows(uint totalBorrows_) public {\n totalBorrows = totalBorrows_;\n }\n\n function setTotalReserves(uint totalReserves_) public {\n totalReserves = totalReserves_;\n }\n\n function getBlockNumber() internal view returns (uint) {\n ComptrollerScenario comptrollerScenario = ComptrollerScenario(address(comptroller));\n return comptrollerScenario.blockNumber();\n }\n}\n\ncontract VBep20DelegateScenarioExtra is VBep20DelegateScenario {\n function iHaveSpoken() public pure returns (string memory) {\n return \"i have spoken\";\n }\n\n function itIsTheWay() public {\n admin = address(1); // make a change to test effect\n }\n\n function babyYoda() public pure {\n revert(\"protect the baby\");\n }\n}\n" + }, + "contracts/test/VBep20MockDelegate.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/VTokens/VToken.sol\";\n\n/**\n * @title Venus's VBep20 Contract\n * @notice VTokens which wrap an EIP-20 underlying\n * @author Venus\n */\ncontract VBep20MockDelegate is VToken, VBep20Interface {\n address public implementation;\n uint internal blockNumber = 100000;\n\n /**\n * @notice Initialize the new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n */\n function initialize(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) public {\n // VToken initialize does the bulk of the work\n super.initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_);\n\n // Set underlying and sanity check it\n underlying = underlying_;\n EIP20Interface(underlying).totalSupply();\n }\n\n /**\n * @notice Called by the delegator on a delegate to initialize it for duty\n * @param data The encoded bytes data for any initialization\n */\n function _becomeImplementation(bytes memory data) public {\n // Shh -- currently unused\n data;\n\n // Shh -- we don't ever want this hook to be marked pure\n if (false) {\n implementation = address(0);\n }\n\n require(msg.sender == admin, \"only the admin may call _becomeImplementation\");\n }\n\n /**\n * @notice Called by the delegator on a delegate to forfeit its responsibility\n */\n function _resignImplementation() public {\n // Shh -- we don't ever want this hook to be marked pure\n if (false) {\n implementation = address(0);\n }\n\n require(msg.sender == admin, \"only the admin may call _resignImplementation\");\n }\n\n function harnessFastForward(uint blocks) public {\n blockNumber += blocks;\n }\n\n /*** User Interface ***/\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function mint(uint mintAmount) external returns (uint) {\n (uint err, ) = mintInternal(mintAmount);\n return err;\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param receiver the account which is receiving the vTokens\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function mintBehalf(address receiver, uint mintAmount) external returns (uint) {\n (uint err, ) = mintBehalfInternal(receiver, mintAmount);\n return err;\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function redeem(uint redeemTokens) external returns (uint) {\n return redeemInternal(msg.sender, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n return redeemUnderlyingInternal(msg.sender, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function borrow(uint borrowAmount) external returns (uint) {\n return borrowInternal(msg.sender, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function repayBorrow(uint repayAmount) external returns (uint) {\n (uint err, ) = repayBorrowInternal(repayAmount);\n return err;\n }\n\n /**\n * @notice Sender repays a borrow belonging to borrower\n * @param borrower the account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) {\n (uint err, ) = repayBorrowBehalfInternal(borrower, repayAmount);\n return err;\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function liquidateBorrow(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint) {\n (uint err, ) = liquidateBorrowInternal(borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n /**\n * @notice The sender adds to reserves.\n * @param addAmount The amount fo underlying token to add as reserves\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _addReserves(uint addAmount) external returns (uint) {\n return _addReservesInternal(addAmount);\n }\n\n /*** Safe Token ***/\n\n /**\n * @notice Gets balance of this contract in terms of the underlying\n * @dev This excludes the value of the current message, if any\n * @return The quantity of underlying tokens owned by this contract\n */\n function getCashPrior() internal view returns (uint) {\n EIP20Interface token = EIP20Interface(underlying);\n return token.balanceOf(address(this));\n }\n\n /**\n * @dev Similar to EIP20 transfer, except it handles a False result from `transferFrom` and reverts in that case.\n * This will revert due to insufficient balance or insufficient allowance.\n * This function returns the actual amount received,\n * which may be less than `amount` if there is a fee attached to the transfer.\n *\n * Note: This wrapper safely handles non-standard BEP-20 tokens that do not return a value.\n * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\n function doTransferIn(address from, uint amount) internal returns (uint) {\n EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying);\n uint balanceBefore = EIP20Interface(underlying).balanceOf(address(this));\n token.transferFrom(from, address(this), amount);\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a compliant BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n require(success, \"TOKEN_TRANSFER_IN_FAILED\");\n\n // Calculate the amount that was *actually* transferred\n uint balanceAfter = EIP20Interface(underlying).balanceOf(address(this));\n require(balanceAfter >= balanceBefore, \"TOKEN_TRANSFER_IN_OVERFLOW\");\n return balanceAfter - balanceBefore; // underflow already checked above, just subtract\n }\n\n /**\n * @dev Similar to EIP20 transfer, except it handles a False success from `transfer` and returns an explanatory\n * error code rather than reverting. If caller has not called checked protocol's balance, this may revert due to\n * insufficient cash held in this contract. If caller has checked protocol's balance prior to this call, and verified\n * it is >= amount, this should not revert in normal conditions.\n *\n * Note: This wrapper safely handles non-standard BEP-20 tokens that do not return a value.\n * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\n function doTransferOut(address payable to, uint amount) internal {\n EIP20NonStandardInterface token = EIP20NonStandardInterface(underlying);\n token.transfer(to, amount);\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a complaint BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n require(success, \"TOKEN_TRANSFER_OUT_FAILED\");\n }\n}\n" + }, + "contracts/test/VRTConverterHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../contracts/Tokens/VRT/VRTConverter.sol\";\n\ncontract VRTConverterHarness is VRTConverter {\n constructor() public VRTConverter() {\n admin = msg.sender;\n }\n\n function balanceOfUser() public view returns (uint256, address) {\n uint256 vrtBalanceOfUser = vrt.balanceOf(msg.sender);\n return (vrtBalanceOfUser, msg.sender);\n }\n\n function setConversionRatio(uint256 _conversionRatio) public onlyAdmin {\n conversionRatio = _conversionRatio;\n }\n\n function setConversionTimeline(uint256 _conversionStartTime, uint256 _conversionPeriod) public onlyAdmin {\n conversionStartTime = _conversionStartTime;\n conversionPeriod = _conversionPeriod;\n conversionEndTime = conversionStartTime.add(conversionPeriod);\n }\n\n function getXVSRedeemedAmount(uint256 vrtAmount) public view returns (uint256) {\n return vrtAmount.mul(conversionRatio).mul(xvsDecimalsMultiplier).div(1e18).div(vrtDecimalsMultiplier);\n }\n}\n" + }, + "contracts/test/VRTVaultHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../contracts/VRTVault/VRTVault.sol\";\n\ncontract VRTVaultHarness is VRTVault {\n uint public blockNumber;\n\n constructor() public VRTVault() {}\n\n function overrideInterestRatePerBlock(uint256 _interestRatePerBlock) public {\n interestRatePerBlock = _interestRatePerBlock;\n }\n\n function balanceOfUser() public view returns (uint256, address) {\n uint256 vrtBalanceOfUser = vrt.balanceOf(msg.sender);\n return (vrtBalanceOfUser, msg.sender);\n }\n\n function harnessFastForward(uint256 blocks) public returns (uint256) {\n blockNumber += blocks;\n return blockNumber;\n }\n\n function setBlockNumber(uint256 number) public {\n blockNumber = number;\n }\n\n function getBlockNumber() public view returns (uint256) {\n return blockNumber;\n }\n}\n" + }, + "contracts/test/XVSHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Tokens/XVS/XVS.sol\";\n\ncontract XVSScenario is XVS {\n constructor(address account) public XVS(account) {}\n\n function transferScenario(address[] calldata destinations, uint256 amount) external returns (bool) {\n for (uint i = 0; i < destinations.length; i++) {\n address dst = destinations[i];\n _transferTokens(msg.sender, dst, uint96(amount));\n }\n return true;\n }\n\n function transferFromScenario(address[] calldata froms, uint256 amount) external returns (bool) {\n for (uint i = 0; i < froms.length; i++) {\n address from = froms[i];\n _transferTokens(from, msg.sender, uint96(amount));\n }\n return true;\n }\n\n function generateCheckpoints(uint count, uint offset) external {\n for (uint i = 1 + offset; i <= count + offset; i++) {\n checkpoints[msg.sender][numCheckpoints[msg.sender]++] = Checkpoint(uint32(i), uint96(i));\n }\n }\n}\n" + }, + "contracts/test/XVSVaultScenario.sol": { + "content": "pragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../XVSVault/XVSVault.sol\";\n\ncontract XVSVaultScenario is XVSVault {\n using SafeMath for uint256;\n\n constructor() public {\n admin = msg.sender;\n }\n\n function pushOldWithdrawalRequest(\n UserInfo storage _user,\n WithdrawalRequest[] storage _requests,\n uint _amount,\n uint _lockedUntil\n ) internal {\n uint i = _requests.length;\n _requests.push(WithdrawalRequest(0, 0, 0));\n // Keep it sorted so that the first to get unlocked request is always at the end\n for (; i > 0 && _requests[i - 1].lockedUntil <= _lockedUntil; --i) {\n _requests[i] = _requests[i - 1];\n }\n _requests[i] = WithdrawalRequest(_amount, uint128(_lockedUntil), 0);\n _user.pendingWithdrawals = _user.pendingWithdrawals.add(_amount);\n }\n\n function requestOldWithdrawal(address _rewardToken, uint256 _pid, uint256 _amount) external nonReentrant {\n _ensureValidPool(_rewardToken, _pid);\n require(_amount > 0, \"requested amount cannot be zero\");\n UserInfo storage user = userInfos[_rewardToken][_pid][msg.sender];\n require(user.amount >= user.pendingWithdrawals.add(_amount), \"requested amount is invalid\");\n\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][msg.sender];\n uint lockedUntil = pool.lockPeriod.add(block.timestamp);\n\n pushOldWithdrawalRequest(user, requests, _amount, lockedUntil);\n\n // Update Delegate Amount\n if (_rewardToken == address(xvsAddress)) {\n _moveDelegates(delegates[msg.sender], address(0), uint96(_amount));\n }\n\n emit RequestedWithdrawal(msg.sender, _rewardToken, _pid, _amount);\n }\n\n function transferReward(address rewardToken, address user, uint256 amount) external {\n _transferReward(rewardToken, user, amount);\n }\n}\n" + }, + "contracts/test/XVSVestingHarness.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../contracts/Tokens/XVS/XVSVesting.sol\";\n\ncontract XVSVestingHarness is XVSVesting {\n address public constant ZERO_ADDRESS = 0x0000000000000000000000000000000000000000;\n\n constructor() public XVSVesting() {\n admin = msg.sender;\n }\n\n uint public blockNumber;\n\n function recoverXVS(address recoveryAddress) public payable {\n uint256 xvsBalance = xvs.balanceOf(address(this));\n xvs.safeTransferFrom(address(this), recoveryAddress, xvsBalance);\n }\n\n function overWriteVRTConversionAddress() public {\n vrtConversionAddress = ZERO_ADDRESS;\n }\n\n function computeWithdrawableAmount(\n uint256 amount,\n uint256 vestingStartTime,\n uint256 withdrawnAmount\n ) public view returns (uint256 vestedAmount, uint256 toWithdraw) {\n (vestedAmount, toWithdraw) = super.calculateWithdrawableAmount(amount, vestingStartTime, withdrawnAmount);\n return (vestedAmount, toWithdraw);\n }\n\n function computeVestedAmount(\n uint256 vestingAmount,\n uint256 vestingStartTime,\n uint256 currentTime\n ) public view returns (uint256) {\n return super.calculateVestedAmount(vestingAmount, vestingStartTime, currentTime);\n }\n\n function getVestingCount(address beneficiary) public view returns (uint256) {\n return vestings[beneficiary].length;\n }\n\n function getVestedAmount(address recipient) public view nonZeroAddress(recipient) returns (uint256) {\n VestingRecord[] memory vestingsOfRecipient = vestings[recipient];\n uint256 vestingCount = vestingsOfRecipient.length;\n uint256 totalVestedAmount = 0;\n uint256 currentTime = getCurrentTime();\n\n for (uint i = 0; i < vestingCount; i++) {\n VestingRecord memory vesting = vestingsOfRecipient[i];\n uint256 vestedAmount = calculateVestedAmount(vesting.amount, vesting.startTime, currentTime);\n totalVestedAmount = totalVestedAmount.add(vestedAmount);\n }\n\n return totalVestedAmount;\n }\n}\n" + }, + "contracts/Tokens/EIP20Interface.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title BEP 20 Token Standard Interface\n * https://eips.ethereum.org/EIPS/eip-20\n */\ninterface EIP20Interface {\n function name() external view returns (string memory);\n\n function symbol() external view returns (string memory);\n\n function decimals() external view returns (uint8);\n\n /**\n * @notice Get the total number of tokens in circulation\n * @return The supply of tokens\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @notice Gets the balance of the specified address\n * @param owner The address from which the balance will be retrieved\n * @return balance\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return success whether or not the transfer succeeded\n */\n function transfer(address dst, uint256 amount) external returns (bool success);\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return success whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved (-1 means infinite)\n * @return success whether or not the approval succeeded\n */\n function approve(address spender, uint256 amount) external returns (bool success);\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return remaining The number of tokens allowed to be spent\n */\n function allowance(address owner, address spender) external view returns (uint256 remaining);\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n}\n" + }, + "contracts/Tokens/EIP20NonStandardInterface.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title EIP20NonStandardInterface\n * @dev Version of BEP20 with no return values for `transfer` and `transferFrom`\n * See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\ninterface EIP20NonStandardInterface {\n /**\n * @notice Get the total number of tokens in circulation\n * @return The supply of tokens\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @notice Gets the balance of the specified address\n * @param owner The address from which the balance will be retrieved\n * @return balance of the owner\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n ///\n /// !!!!!!!!!!!!!!\n /// !!! NOTICE !!! `transfer` does not return a value, in violation of the BEP-20 specification\n /// !!!!!!!!!!!!!!\n ///\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n */\n function transfer(address dst, uint256 amount) external;\n\n ///\n /// !!!!!!!!!!!!!!\n /// !!! NOTICE !!! `transferFrom` does not return a value, in violation of the BEP-20 specification\n /// !!!!!!!!!!!!!!\n ///\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n */\n function transferFrom(address src, address dst, uint256 amount) external;\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved\n * @return success Whether or not the approval succeeded\n */\n function approve(address spender, uint256 amount) external returns (bool success);\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return remaining The number of tokens allowed to be spent\n */\n function allowance(address owner, address spender) external view returns (uint256 remaining);\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n}\n" + }, + "contracts/Tokens/Prime/IPrime.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.5.16;\npragma experimental ABIEncoderV2;\n\n/**\n * @title IPrime\n * @author Venus\n * @notice Interface for Prime Token\n */\ninterface IPrime {\n /**\n * @notice Executed by XVSVault whenever user's XVSVault balance changes\n * @param user the account address whose balance was updated\n */\n function xvsUpdated(address user) external;\n\n /**\n * @notice accrues interest and updates score for an user for a specific market\n * @param user the account address for which to accrue interest and update score\n * @param market the market for which to accrue interest and update score\n */\n function accrueInterestAndUpdateScore(address user, address market) external;\n\n /**\n * @notice Distributes income from market since last distribution\n * @param vToken the market for which to distribute the income\n */\n function accrueInterest(address vToken) external;\n\n /**\n * @notice Returns if user is a prime holder\n * @param isPrimeHolder returns if the user is a prime holder\n */\n function isUserPrimeHolder(address user) external view returns (bool isPrimeHolder);\n}\n" + }, + "contracts/Tokens/VAI/lib.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\npragma solidity ^0.5.16;\n\ncontract LibNote {\n event LogNote(\n bytes4 indexed sig,\n address indexed usr,\n bytes32 indexed arg1,\n bytes32 indexed arg2,\n bytes data\n ) anonymous;\n\n modifier note() {\n _;\n assembly {\n // log an 'anonymous' event with a constant 6 words of calldata\n // and four indexed topics: selector, caller, arg1 and arg2\n let mark := msize() // end of memory ensures zero\n mstore(0x40, add(mark, 288)) // update free memory pointer\n mstore(mark, 0x20) // bytes type data offset\n mstore(add(mark, 0x20), 224) // bytes size (padded)\n calldatacopy(add(mark, 0x40), 0, 224) // bytes payload\n log4(\n mark,\n 288, // calldata\n shl(224, shr(224, calldataload(0))), // msg.sig\n caller(), // msg.sender\n calldataload(4), // arg1\n calldataload(36) // arg2\n )\n }\n }\n}\n" + }, + "contracts/Tokens/VAI/VAI.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\n\n// Copyright (C) 2017, 2018, 2019 dbrock, rain, mrchico\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity ^0.5.16;\n\nimport \"./lib.sol\";\n\ncontract VAI is LibNote {\n // --- Auth ---\n mapping(address => uint256) public wards;\n\n function rely(address guy) external note auth {\n wards[guy] = 1;\n }\n\n function deny(address guy) external note auth {\n wards[guy] = 0;\n }\n\n modifier auth() {\n require(wards[msg.sender] == 1, \"VAI/not-authorized\");\n _;\n }\n\n // --- BEP20 Data ---\n string public constant name = \"VAI Stablecoin\";\n string public constant symbol = \"VAI\";\n string public constant version = \"1\";\n uint8 public constant decimals = 18;\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n mapping(address => mapping(address => uint256)) public allowance;\n mapping(address => uint256) public nonces;\n\n event Approval(address indexed src, address indexed guy, uint256 wad);\n event Transfer(address indexed src, address indexed dst, uint256 wad);\n\n // --- Math ---\n function add(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require((z = x + y) >= x, \"VAI math error\");\n }\n\n function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require((z = x - y) <= x, \"VAI math error\");\n }\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n constructor(uint256 chainId_) public {\n wards[msg.sender] = 1;\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n // --- Token ---\n function transfer(address dst, uint256 wad) external returns (bool) {\n return transferFrom(msg.sender, dst, wad);\n }\n\n function transferFrom(address src, address dst, uint256 wad) public returns (bool) {\n require(balanceOf[src] >= wad, \"VAI/insufficient-balance\");\n if (src != msg.sender && allowance[src][msg.sender] != uint256(-1)) {\n require(allowance[src][msg.sender] >= wad, \"VAI/insufficient-allowance\");\n allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);\n }\n balanceOf[src] = sub(balanceOf[src], wad);\n balanceOf[dst] = add(balanceOf[dst], wad);\n emit Transfer(src, dst, wad);\n return true;\n }\n\n function mint(address usr, uint256 wad) external auth {\n balanceOf[usr] = add(balanceOf[usr], wad);\n totalSupply = add(totalSupply, wad);\n emit Transfer(address(0), usr, wad);\n }\n\n function burn(address usr, uint256 wad) external {\n require(balanceOf[usr] >= wad, \"VAI/insufficient-balance\");\n if (usr != msg.sender && allowance[usr][msg.sender] != uint256(-1)) {\n require(allowance[usr][msg.sender] >= wad, \"VAI/insufficient-allowance\");\n allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad);\n }\n balanceOf[usr] = sub(balanceOf[usr], wad);\n totalSupply = sub(totalSupply, wad);\n emit Transfer(usr, address(0), wad);\n }\n\n function approve(address usr, uint256 wad) external returns (bool) {\n allowance[msg.sender][usr] = wad;\n emit Approval(msg.sender, usr, wad);\n return true;\n }\n\n // --- Alias ---\n function push(address usr, uint256 wad) external {\n transferFrom(msg.sender, usr, wad);\n }\n\n function pull(address usr, uint256 wad) external {\n transferFrom(usr, msg.sender, wad);\n }\n\n function move(address src, address dst, uint256 wad) external {\n transferFrom(src, dst, wad);\n }\n\n // --- Approve by signature ---\n function permit(\n address holder,\n address spender,\n uint256 nonce,\n uint256 expiry,\n bool allowed,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(abi.encode(PERMIT_TYPEHASH, holder, spender, nonce, expiry, allowed))\n )\n );\n\n require(holder != address(0), \"VAI/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"VAI/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"VAI/permit-expired\");\n require(nonce == nonces[holder]++, \"VAI/invalid-nonce\");\n uint256 wad = allowed ? uint256(-1) : 0;\n allowance[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n}\n" + }, + "contracts/Tokens/VAI/VAIController.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.5.16;\n\nimport { PriceOracle } from \"../../Oracle/PriceOracle.sol\";\nimport { VAIControllerErrorReporter } from \"../../Utils/ErrorReporter.sol\";\nimport { Exponential } from \"../../Utils/Exponential.sol\";\nimport { ComptrollerInterface } from \"../../Comptroller/ComptrollerInterface.sol\";\nimport { IAccessControlManagerV5 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\";\nimport { VToken, EIP20Interface } from \"../VTokens/VToken.sol\";\nimport { VAIUnitroller, VAIControllerStorageG4 } from \"./VAIUnitroller.sol\";\nimport { VAIControllerInterface } from \"./VAIControllerInterface.sol\";\nimport { VAI } from \"./VAI.sol\";\nimport { IPrime } from \"../Prime/IPrime.sol\";\nimport { VTokenInterface } from \"../VTokens/VTokenInterfaces.sol\";\n\n/**\n * @title VAI Comptroller\n * @author Venus\n * @notice This is the implementation contract for the VAIUnitroller proxy\n */\ncontract VAIController is VAIControllerInterface, VAIControllerStorageG4, VAIControllerErrorReporter, Exponential {\n /// @notice Initial index used in interest computations\n uint256 public constant INITIAL_VAI_MINT_INDEX = 1e18;\n\n /// @notice Emitted when Comptroller is changed\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\n\n /// @notice Emitted when mint for prime holder is changed\n event MintOnlyForPrimeHolder(bool previousMintEnabledOnlyForPrimeHolder, bool newMintEnabledOnlyForPrimeHolder);\n\n /// @notice Emitted when Prime is changed\n event NewPrime(address oldPrime, address newPrime);\n\n /// @notice Event emitted when VAI is minted\n event MintVAI(address minter, uint256 mintVAIAmount);\n\n /// @notice Event emitted when VAI is repaid\n event RepayVAI(address payer, address borrower, uint256 repayVAIAmount);\n\n /// @notice Event emitted when a borrow is liquidated\n event LiquidateVAI(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n address vTokenCollateral,\n uint256 seizeTokens\n );\n\n /// @notice Emitted when treasury guardian is changed\n event NewTreasuryGuardian(address oldTreasuryGuardian, address newTreasuryGuardian);\n\n /// @notice Emitted when treasury address is changed\n event NewTreasuryAddress(address oldTreasuryAddress, address newTreasuryAddress);\n\n /// @notice Emitted when treasury percent is changed\n event NewTreasuryPercent(uint256 oldTreasuryPercent, uint256 newTreasuryPercent);\n\n /// @notice Event emitted when VAIs are minted and fee are transferred\n event MintFee(address minter, uint256 feeAmount);\n\n /// @notice Emiitted when VAI base rate is changed\n event NewVAIBaseRate(uint256 oldBaseRateMantissa, uint256 newBaseRateMantissa);\n\n /// @notice Emiitted when VAI float rate is changed\n event NewVAIFloatRate(uint256 oldFloatRateMantissa, uint256 newFlatRateMantissa);\n\n /// @notice Emiitted when VAI receiver address is changed\n event NewVAIReceiver(address oldReceiver, address newReceiver);\n\n /// @notice Emiitted when VAI mint cap is changed\n event NewVAIMintCap(uint256 oldMintCap, uint256 newMintCap);\n\n /// @notice Emitted when access control address is changed by admin\n event NewAccessControl(address oldAccessControlAddress, address newAccessControlAddress);\n\n /// @notice Emitted when VAI token address is changed by admin\n event NewVaiToken(address oldVaiToken, address newVaiToken);\n\n function initialize() external onlyAdmin {\n require(vaiMintIndex == 0, \"already initialized\");\n\n vaiMintIndex = INITIAL_VAI_MINT_INDEX;\n accrualBlockNumber = getBlockNumber();\n mintCap = uint256(-1);\n\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\n _notEntered = true;\n }\n\n function _become(VAIUnitroller unitroller) external {\n require(msg.sender == unitroller.admin(), \"only unitroller admin can change brains\");\n require(unitroller._acceptImplementation() == 0, \"change not authorized\");\n }\n\n /**\n * @notice The mintVAI function mints and transfers VAI from the protocol to the user, and adds a borrow balance.\n * The amount minted must be less than the user's Account Liquidity and the mint vai limit.\n * @dev If the Comptroller address is not set, minting is a no-op and the function returns the success code.\n * @param mintVAIAmount The amount of the VAI to be minted.\n * @return 0 on success, otherwise an error code\n */\n // solhint-disable-next-line code-complexity\n function mintVAI(uint256 mintVAIAmount) external nonReentrant returns (uint256) {\n if (address(comptroller) == address(0)) {\n return uint256(Error.NO_ERROR);\n }\n\n _ensureNonzeroAmount(mintVAIAmount);\n _ensureNotPaused();\n accrueVAIInterest();\n\n uint256 err;\n address minter = msg.sender;\n address _vai = vai;\n uint256 vaiTotalSupply = EIP20Interface(_vai).totalSupply();\n\n uint256 vaiNewTotalSupply = add_(vaiTotalSupply, mintVAIAmount);\n require(vaiNewTotalSupply <= mintCap, \"mint cap reached\");\n\n uint256 accountMintableVAI;\n (err, accountMintableVAI) = getMintableVAI(minter);\n require(err == uint256(Error.NO_ERROR), \"could not compute mintable amount\");\n\n // check that user have sufficient mintableVAI balance\n require(mintVAIAmount <= accountMintableVAI, \"minting more than allowed\");\n\n // Calculate the minted balance based on interest index\n uint256 totalMintedVAI = comptroller.mintedVAIs(minter);\n\n if (totalMintedVAI > 0) {\n uint256 repayAmount = getVAIRepayAmount(minter);\n uint256 remainedAmount = sub_(repayAmount, totalMintedVAI);\n pastVAIInterest[minter] = add_(pastVAIInterest[minter], remainedAmount);\n totalMintedVAI = repayAmount;\n }\n\n uint256 accountMintVAINew = add_(totalMintedVAI, mintVAIAmount);\n err = comptroller.setMintedVAIOf(minter, accountMintVAINew);\n require(err == uint256(Error.NO_ERROR), \"comptroller rejection\");\n\n uint256 remainedAmount;\n if (treasuryPercent != 0) {\n uint256 feeAmount = div_(mul_(mintVAIAmount, treasuryPercent), 1e18);\n remainedAmount = sub_(mintVAIAmount, feeAmount);\n VAI(_vai).mint(treasuryAddress, feeAmount);\n\n emit MintFee(minter, feeAmount);\n } else {\n remainedAmount = mintVAIAmount;\n }\n\n VAI(_vai).mint(minter, remainedAmount);\n vaiMinterInterestIndex[minter] = vaiMintIndex;\n\n emit MintVAI(minter, remainedAmount);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice The repay function transfers VAI interest into the protocol and burns the rest,\n * reducing the borrower's borrow balance. Before repaying VAI, users must first approve\n * VAIController to access their VAI balance.\n * @dev If the Comptroller address is not set, repayment is a no-op and the function returns the success code.\n * @param amount The amount of VAI to be repaid.\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function repayVAI(uint256 amount) external nonReentrant returns (uint256, uint256) {\n return _repayVAI(msg.sender, amount);\n }\n\n /**\n * @notice The repay on behalf function transfers VAI interest into the protocol and burns the rest,\n * reducing the borrower's borrow balance. Borrowed VAIs are repaid by another user (possibly the borrower).\n * Before repaying VAI, the payer must first approve VAIController to access their VAI balance.\n * @dev If the Comptroller address is not set, repayment is a no-op and the function returns the success code.\n * @param borrower The account to repay the debt for.\n * @param amount The amount of VAI to be repaid.\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function repayVAIBehalf(address borrower, uint256 amount) external nonReentrant returns (uint256, uint256) {\n _ensureNonzeroAddress(borrower);\n return _repayVAI(borrower, amount);\n }\n\n /**\n * @dev Checks the parameters and the protocol state, accrues interest, and invokes repayVAIFresh.\n * @dev If the Comptroller address is not set, repayment is a no-op and the function returns the success code.\n * @param borrower The account to repay the debt for.\n * @param amount The amount of VAI to be repaid.\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function _repayVAI(address borrower, uint256 amount) internal returns (uint256, uint256) {\n if (address(comptroller) == address(0)) {\n return (0, 0);\n }\n _ensureNonzeroAmount(amount);\n _ensureNotPaused();\n\n accrueVAIInterest();\n return repayVAIFresh(msg.sender, borrower, amount);\n }\n\n /**\n * @dev Repay VAI, expecting interest to be accrued\n * @dev Borrowed VAIs are repaid by another user (possibly the borrower).\n * @param payer the account paying off the VAI\n * @param borrower the account with the debt being payed off\n * @param repayAmount the amount of VAI being repaid\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function repayVAIFresh(address payer, address borrower, uint256 repayAmount) internal returns (uint256, uint256) {\n (uint256 burn, uint256 partOfCurrentInterest, uint256 partOfPastInterest) = getVAICalculateRepayAmount(\n borrower,\n repayAmount\n );\n\n VAI _vai = VAI(vai);\n _vai.burn(payer, burn);\n bool success = _vai.transferFrom(payer, receiver, partOfCurrentInterest);\n require(success == true, \"failed to transfer VAI fee\");\n\n uint256 vaiBalanceBorrower = comptroller.mintedVAIs(borrower);\n\n uint256 accountVAINew = sub_(sub_(vaiBalanceBorrower, burn), partOfPastInterest);\n pastVAIInterest[borrower] = sub_(pastVAIInterest[borrower], partOfPastInterest);\n\n uint256 error = comptroller.setMintedVAIOf(borrower, accountVAINew);\n // We have to revert upon error since side-effects already happened at this point\n require(error == uint256(Error.NO_ERROR), \"comptroller rejection\");\n\n uint256 repaidAmount = add_(burn, partOfCurrentInterest);\n emit RepayVAI(payer, borrower, repaidAmount);\n\n return (uint256(Error.NO_ERROR), repaidAmount);\n }\n\n /**\n * @notice The sender liquidates the vai minters collateral. The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of vai to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function liquidateVAI(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external nonReentrant returns (uint256, uint256) {\n _ensureNotPaused();\n\n uint256 error = vTokenCollateral.accrueInterest();\n if (error != uint256(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n return (fail(Error(error), FailureInfo.VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\n }\n\n // liquidateVAIFresh emits borrow-specific logs on errors, so we don't need to\n return liquidateVAIFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\n }\n\n /**\n * @notice The liquidator liquidates the borrowers collateral by repay borrowers VAI.\n * The collateral seized is transferred to the liquidator.\n * @dev If the Comptroller address is not set, liquidation is a no-op and the function returns the success code.\n * @param liquidator The address repaying the VAI and seizing collateral\n * @param borrower The borrower of this VAI to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the VAI to repay\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol)\n * @return Actual repayment amount\n */\n function liquidateVAIFresh(\n address liquidator,\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) internal returns (uint256, uint256) {\n if (address(comptroller) != address(0)) {\n accrueVAIInterest();\n\n /* Fail if liquidate not allowed */\n uint256 allowed = comptroller.liquidateBorrowAllowed(\n address(this),\n address(vTokenCollateral),\n liquidator,\n borrower,\n repayAmount\n );\n if (allowed != 0) {\n return (failOpaque(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\n }\n\n /* Verify vTokenCollateral market's block number equals current block number */\n //if (vTokenCollateral.accrualBlockNumber() != accrualBlockNumber) {\n if (vTokenCollateral.accrualBlockNumber() != getBlockNumber()) {\n return (fail(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n return (fail(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\n }\n\n /* Fail if repayAmount = 0 */\n if (repayAmount == 0) {\n return (fail(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\n }\n\n /* Fail if repayAmount = -1 */\n if (repayAmount == uint256(-1)) {\n return (fail(Error.REJECTION, FailureInfo.VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\n }\n\n /* Fail if repayVAI fails */\n (uint256 repayBorrowError, uint256 actualRepayAmount) = repayVAIFresh(liquidator, borrower, repayAmount);\n if (repayBorrowError != uint256(Error.NO_ERROR)) {\n return (fail(Error(repayBorrowError), FailureInfo.VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We calculate the number of collateral tokens that will be seized */\n (uint256 amountSeizeError, uint256 seizeTokens) = comptroller.liquidateVAICalculateSeizeTokens(\n address(vTokenCollateral),\n actualRepayAmount\n );\n require(\n amountSeizeError == uint256(Error.NO_ERROR),\n \"VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\"\n );\n\n /* Revert if borrower collateral token balance < seizeTokens */\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \"VAI_LIQUIDATE_SEIZE_TOO_MUCH\");\n\n uint256 seizeError;\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\n\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\n require(seizeError == uint256(Error.NO_ERROR), \"token seizure failed\");\n\n /* We emit a LiquidateBorrow event */\n emit LiquidateVAI(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\n\n /* We call the defense hook */\n comptroller.liquidateBorrowVerify(\n address(this),\n address(vTokenCollateral),\n liquidator,\n borrower,\n actualRepayAmount,\n seizeTokens\n );\n\n return (uint256(Error.NO_ERROR), actualRepayAmount);\n }\n }\n\n /*** Admin Functions ***/\n\n /**\n * @notice Sets a new comptroller\n * @dev Admin function to set a new comptroller\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setComptroller(ComptrollerInterface comptroller_) external returns (uint256) {\n // Check caller is admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_COMPTROLLER_OWNER_CHECK);\n }\n\n ComptrollerInterface oldComptroller = comptroller;\n comptroller = comptroller_;\n emit NewComptroller(oldComptroller, comptroller_);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Set the prime token contract address\n * @param prime_ The new address of the prime token contract\n */\n function setPrimeToken(address prime_) external onlyAdmin {\n emit NewPrime(prime, prime_);\n prime = prime_;\n }\n\n /**\n * @notice Set the VAI token contract address\n * @param vai_ The new address of the VAI token contract\n */\n function setVAIToken(address vai_) external onlyAdmin {\n emit NewVaiToken(vai, vai_);\n vai = vai_;\n }\n\n /**\n * @notice Toggle mint only for prime holder\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function toggleOnlyPrimeHolderMint() external returns (uint256) {\n _ensureAllowed(\"toggleOnlyPrimeHolderMint()\");\n\n if (!mintEnabledOnlyForPrimeHolder && prime == address(0)) {\n return uint256(Error.REJECTION);\n }\n\n emit MintOnlyForPrimeHolder(mintEnabledOnlyForPrimeHolder, !mintEnabledOnlyForPrimeHolder);\n mintEnabledOnlyForPrimeHolder = !mintEnabledOnlyForPrimeHolder;\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @dev Local vars for avoiding stack-depth limits in calculating account total supply balance.\n * Note that `vTokenBalance` is the number of vTokens the account owns in the market,\n * whereas `borrowBalance` is the amount of underlying that the account has borrowed.\n */\n struct AccountAmountLocalVars {\n uint256 oErr;\n MathError mErr;\n uint256 sumSupply;\n uint256 marketSupply;\n uint256 sumBorrowPlusEffects;\n uint256 vTokenBalance;\n uint256 borrowBalance;\n uint256 exchangeRateMantissa;\n uint256 oraclePriceMantissa;\n Exp exchangeRate;\n Exp oraclePrice;\n Exp tokensToDenom;\n }\n\n /**\n * @notice Function that returns the amount of VAI a user can mint based on their account liquidy and the VAI mint rate\n * If mintEnabledOnlyForPrimeHolder is true, only Prime holders are able to mint VAI\n * @param minter The account to check mintable VAI\n * @return Error code (0=success, otherwise a failure, see ErrorReporter.sol for details)\n * @return Mintable amount (with 18 decimals)\n */\n // solhint-disable-next-line code-complexity\n function getMintableVAI(address minter) public view returns (uint256, uint256) {\n if (mintEnabledOnlyForPrimeHolder && !IPrime(prime).isUserPrimeHolder(minter)) {\n return (uint256(Error.REJECTION), 0);\n }\n\n PriceOracle oracle = comptroller.oracle();\n VToken[] memory enteredMarkets = comptroller.getAssetsIn(minter);\n\n AccountAmountLocalVars memory vars; // Holds all our calculation results\n\n uint256 accountMintableVAI;\n uint256 i;\n\n /**\n * We use this formula to calculate mintable VAI amount.\n * totalSupplyAmount * VAIMintRate - (totalBorrowAmount + mintedVAIOf)\n */\n uint256 marketsCount = enteredMarkets.length;\n for (i = 0; i < marketsCount; i++) {\n (vars.oErr, vars.vTokenBalance, vars.borrowBalance, vars.exchangeRateMantissa) = enteredMarkets[i]\n .getAccountSnapshot(minter);\n if (vars.oErr != 0) {\n // semi-opaque error code, we assume NO_ERROR == 0 is invariant between upgrades\n return (uint256(Error.SNAPSHOT_ERROR), 0);\n }\n vars.exchangeRate = Exp({ mantissa: vars.exchangeRateMantissa });\n\n // Get the normalized price of the asset\n vars.oraclePriceMantissa = oracle.getUnderlyingPrice(enteredMarkets[i]);\n if (vars.oraclePriceMantissa == 0) {\n return (uint256(Error.PRICE_ERROR), 0);\n }\n vars.oraclePrice = Exp({ mantissa: vars.oraclePriceMantissa });\n\n (vars.mErr, vars.tokensToDenom) = mulExp(vars.exchangeRate, vars.oraclePrice);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n // marketSupply = tokensToDenom * vTokenBalance\n (vars.mErr, vars.marketSupply) = mulScalarTruncate(vars.tokensToDenom, vars.vTokenBalance);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n (, uint256 collateralFactorMantissa) = comptroller.markets(address(enteredMarkets[i]));\n (vars.mErr, vars.marketSupply) = mulUInt(vars.marketSupply, collateralFactorMantissa);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n (vars.mErr, vars.marketSupply) = divUInt(vars.marketSupply, 1e18);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n (vars.mErr, vars.sumSupply) = addUInt(vars.sumSupply, vars.marketSupply);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n // sumBorrowPlusEffects += oraclePrice * borrowBalance\n (vars.mErr, vars.sumBorrowPlusEffects) = mulScalarTruncateAddUInt(\n vars.oraclePrice,\n vars.borrowBalance,\n vars.sumBorrowPlusEffects\n );\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n }\n\n uint256 totalMintedVAI = comptroller.mintedVAIs(minter);\n uint256 repayAmount = 0;\n\n if (totalMintedVAI > 0) {\n repayAmount = getVAIRepayAmount(minter);\n }\n\n (vars.mErr, vars.sumBorrowPlusEffects) = addUInt(vars.sumBorrowPlusEffects, repayAmount);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.MATH_ERROR), 0);\n }\n\n (vars.mErr, accountMintableVAI) = mulUInt(vars.sumSupply, comptroller.vaiMintRate());\n require(vars.mErr == MathError.NO_ERROR, \"VAI_MINT_AMOUNT_CALCULATION_FAILED\");\n\n (vars.mErr, accountMintableVAI) = divUInt(accountMintableVAI, 10000);\n require(vars.mErr == MathError.NO_ERROR, \"VAI_MINT_AMOUNT_CALCULATION_FAILED\");\n\n (vars.mErr, accountMintableVAI) = subUInt(accountMintableVAI, vars.sumBorrowPlusEffects);\n if (vars.mErr != MathError.NO_ERROR) {\n return (uint256(Error.REJECTION), 0);\n }\n\n return (uint256(Error.NO_ERROR), accountMintableVAI);\n }\n\n /**\n * @notice Update treasury data\n * @param newTreasuryGuardian New Treasury Guardian address\n * @param newTreasuryAddress New Treasury Address\n * @param newTreasuryPercent New fee percentage for minting VAI that is sent to the treasury\n */\n function _setTreasuryData(\n address newTreasuryGuardian,\n address newTreasuryAddress,\n uint256 newTreasuryPercent\n ) external returns (uint256) {\n // Check caller is admin\n if (!(msg.sender == admin || msg.sender == treasuryGuardian)) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_TREASURY_OWNER_CHECK);\n }\n\n require(newTreasuryPercent < 1e18, \"treasury percent cap overflow\");\n\n address oldTreasuryGuardian = treasuryGuardian;\n address oldTreasuryAddress = treasuryAddress;\n uint256 oldTreasuryPercent = treasuryPercent;\n\n treasuryGuardian = newTreasuryGuardian;\n treasuryAddress = newTreasuryAddress;\n treasuryPercent = newTreasuryPercent;\n\n emit NewTreasuryGuardian(oldTreasuryGuardian, newTreasuryGuardian);\n emit NewTreasuryAddress(oldTreasuryAddress, newTreasuryAddress);\n emit NewTreasuryPercent(oldTreasuryPercent, newTreasuryPercent);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Gets yearly VAI interest rate based on the VAI price\n * @return uint256 Yearly VAI interest rate\n */\n function getVAIRepayRate() public view returns (uint256) {\n PriceOracle oracle = comptroller.oracle();\n MathError mErr;\n\n if (baseRateMantissa > 0) {\n if (floatRateMantissa > 0) {\n uint256 oraclePrice = oracle.getUnderlyingPrice(VToken(getVAIAddress()));\n if (1e18 > oraclePrice) {\n uint256 delta;\n uint256 rate;\n\n (mErr, delta) = subUInt(1e18, oraclePrice);\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n (mErr, delta) = mulUInt(delta, floatRateMantissa);\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n (mErr, delta) = divUInt(delta, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n (mErr, rate) = addUInt(delta, baseRateMantissa);\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n return rate;\n } else {\n return baseRateMantissa;\n }\n } else {\n return baseRateMantissa;\n }\n } else {\n return 0;\n }\n }\n\n /**\n * @notice Get interest rate per block\n * @return uint256 Interest rate per bock\n */\n function getVAIRepayRatePerBlock() public view returns (uint256) {\n uint256 yearlyRate = getVAIRepayRate();\n\n MathError mErr;\n uint256 rate;\n\n (mErr, rate) = divUInt(yearlyRate, getBlocksPerYear());\n require(mErr == MathError.NO_ERROR, \"VAI_REPAY_RATE_CALCULATION_FAILED\");\n\n return rate;\n }\n\n /**\n * @notice Get the last updated interest index for a VAI Minter\n * @param minter Address of VAI minter\n * @return uint256 Returns the interest rate index for a minter\n */\n function getVAIMinterInterestIndex(address minter) public view returns (uint256) {\n uint256 storedIndex = vaiMinterInterestIndex[minter];\n // If the user minted VAI before the stability fee was introduced, accrue\n // starting from stability fee launch\n if (storedIndex == 0) {\n return INITIAL_VAI_MINT_INDEX;\n }\n return storedIndex;\n }\n\n /**\n * @notice Get the current total VAI a user needs to repay\n * @param account The address of the VAI borrower\n * @return (uint256) The total amount of VAI the user needs to repay\n */\n function getVAIRepayAmount(address account) public view returns (uint256) {\n MathError mErr;\n uint256 delta;\n\n uint256 amount = comptroller.mintedVAIs(account);\n uint256 interest = pastVAIInterest[account];\n uint256 totalMintedVAI;\n uint256 newInterest;\n\n (mErr, totalMintedVAI) = subUInt(amount, interest);\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, delta) = subUInt(vaiMintIndex, getVAIMinterInterestIndex(account));\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, newInterest) = mulUInt(delta, totalMintedVAI);\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, newInterest) = divUInt(newInterest, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, amount) = addUInt(amount, newInterest);\n require(mErr == MathError.NO_ERROR, \"VAI_TOTAL_REPAY_AMOUNT_CALCULATION_FAILED\");\n\n return amount;\n }\n\n /**\n * @notice Calculate how much VAI the user needs to repay\n * @param borrower The address of the VAI borrower\n * @param repayAmount The amount of VAI being returned\n * @return Amount of VAI to be burned\n * @return Amount of VAI the user needs to pay in current interest\n * @return Amount of VAI the user needs to pay in past interest\n */\n function getVAICalculateRepayAmount(\n address borrower,\n uint256 repayAmount\n ) public view returns (uint256, uint256, uint256) {\n MathError mErr;\n uint256 totalRepayAmount = getVAIRepayAmount(borrower);\n uint256 currentInterest;\n\n (mErr, currentInterest) = subUInt(totalRepayAmount, comptroller.mintedVAIs(borrower));\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, currentInterest) = addUInt(pastVAIInterest[borrower], currentInterest);\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n\n uint256 burn;\n uint256 partOfCurrentInterest = currentInterest;\n uint256 partOfPastInterest = pastVAIInterest[borrower];\n\n if (repayAmount >= totalRepayAmount) {\n (mErr, burn) = subUInt(totalRepayAmount, currentInterest);\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n } else {\n uint256 delta;\n\n (mErr, delta) = mulUInt(repayAmount, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_PART_CALCULATION_FAILED\");\n\n (mErr, delta) = divUInt(delta, totalRepayAmount);\n require(mErr == MathError.NO_ERROR, \"VAI_PART_CALCULATION_FAILED\");\n\n uint256 totalMintedAmount;\n (mErr, totalMintedAmount) = subUInt(totalRepayAmount, currentInterest);\n require(mErr == MathError.NO_ERROR, \"VAI_MINTED_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, burn) = mulUInt(totalMintedAmount, delta);\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, burn) = divUInt(burn, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_BURN_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, partOfCurrentInterest) = mulUInt(currentInterest, delta);\n require(mErr == MathError.NO_ERROR, \"VAI_CURRENT_INTEREST_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, partOfCurrentInterest) = divUInt(partOfCurrentInterest, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_CURRENT_INTEREST_AMOUNT_CALCULATION_FAILED\");\n\n (mErr, partOfPastInterest) = mulUInt(pastVAIInterest[borrower], delta);\n require(mErr == MathError.NO_ERROR, \"VAI_PAST_INTEREST_CALCULATION_FAILED\");\n\n (mErr, partOfPastInterest) = divUInt(partOfPastInterest, 1e18);\n require(mErr == MathError.NO_ERROR, \"VAI_PAST_INTEREST_CALCULATION_FAILED\");\n }\n\n return (burn, partOfCurrentInterest, partOfPastInterest);\n }\n\n /**\n * @notice Accrue interest on outstanding minted VAI\n */\n function accrueVAIInterest() public {\n MathError mErr;\n uint256 delta;\n\n (mErr, delta) = mulUInt(getVAIRepayRatePerBlock(), getBlockNumber() - accrualBlockNumber);\n require(mErr == MathError.NO_ERROR, \"VAI_INTEREST_ACCRUE_FAILED\");\n\n (mErr, delta) = addUInt(delta, vaiMintIndex);\n require(mErr == MathError.NO_ERROR, \"VAI_INTEREST_ACCRUE_FAILED\");\n\n vaiMintIndex = delta;\n accrualBlockNumber = getBlockNumber();\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlAddress New address for the access control\n */\n function setAccessControl(address newAccessControlAddress) external onlyAdmin {\n _ensureNonzeroAddress(newAccessControlAddress);\n\n address oldAccessControlAddress = accessControl;\n accessControl = newAccessControlAddress;\n emit NewAccessControl(oldAccessControlAddress, accessControl);\n }\n\n /**\n * @notice Set VAI borrow base rate\n * @param newBaseRateMantissa the base rate multiplied by 10**18\n */\n function setBaseRate(uint256 newBaseRateMantissa) external {\n _ensureAllowed(\"setBaseRate(uint256)\");\n\n uint256 old = baseRateMantissa;\n baseRateMantissa = newBaseRateMantissa;\n emit NewVAIBaseRate(old, baseRateMantissa);\n }\n\n /**\n * @notice Set VAI borrow float rate\n * @param newFloatRateMantissa the VAI float rate multiplied by 10**18\n */\n function setFloatRate(uint256 newFloatRateMantissa) external {\n _ensureAllowed(\"setFloatRate(uint256)\");\n\n uint256 old = floatRateMantissa;\n floatRateMantissa = newFloatRateMantissa;\n emit NewVAIFloatRate(old, floatRateMantissa);\n }\n\n /**\n * @notice Set VAI stability fee receiver address\n * @param newReceiver the address of the VAI fee receiver\n */\n function setReceiver(address newReceiver) external onlyAdmin {\n _ensureNonzeroAddress(newReceiver);\n\n address old = receiver;\n receiver = newReceiver;\n emit NewVAIReceiver(old, newReceiver);\n }\n\n /**\n * @notice Set VAI mint cap\n * @param _mintCap the amount of VAI that can be minted\n */\n function setMintCap(uint256 _mintCap) external {\n _ensureAllowed(\"setMintCap(uint256)\");\n\n uint256 old = mintCap;\n mintCap = _mintCap;\n emit NewVAIMintCap(old, _mintCap);\n }\n\n function getBlockNumber() internal view returns (uint256) {\n return block.number;\n }\n\n function getBlocksPerYear() public view returns (uint256) {\n return 10512000; //(24 * 60 * 60 * 365) / 3;\n }\n\n /**\n * @notice Return the address of the VAI token\n * @return The address of VAI\n */\n function getVAIAddress() public view returns (address) {\n return vai;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n /*** Reentrancy Guard ***/\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n function _ensureAllowed(string memory functionSig) private view {\n require(IAccessControlManagerV5(accessControl).isAllowedToCall(msg.sender, functionSig), \"access denied\");\n }\n\n /// @dev Reverts if the protocol is paused\n function _ensureNotPaused() private view {\n require(!comptroller.protocolPaused(), \"protocol is paused\");\n }\n\n /// @dev Reverts if the passed address is zero\n function _ensureNonzeroAddress(address someone) private pure {\n require(someone != address(0), \"can't be zero address\");\n }\n\n /// @dev Reverts if the passed amount is zero\n function _ensureNonzeroAmount(uint256 amount) private pure {\n require(amount > 0, \"amount can't be zero\");\n }\n}\n" + }, + "contracts/Tokens/VAI/VAIControllerInterface.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport { VTokenInterface } from \"../VTokens/VTokenInterfaces.sol\";\n\ncontract VAIControllerInterface {\n function mintVAI(uint256 mintVAIAmount) external returns (uint256);\n\n function repayVAI(uint256 amount) external returns (uint256, uint256);\n\n function repayVAIBehalf(address borrower, uint256 amount) external returns (uint256, uint256);\n\n function liquidateVAI(\n address borrower,\n uint256 repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint256, uint256);\n\n function getMintableVAI(address minter) external view returns (uint256, uint256);\n\n function getVAIAddress() external view returns (address);\n\n function getVAIRepayAmount(address account) external view returns (uint256);\n}\n" + }, + "contracts/Tokens/VAI/VAIControllerStorage.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport { ComptrollerInterface } from \"../../Comptroller/ComptrollerInterface.sol\";\n\ncontract VAIUnitrollerAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of Unitroller\n */\n address public vaiControllerImplementation;\n\n /**\n * @notice Pending brains of Unitroller\n */\n address public pendingVAIControllerImplementation;\n}\n\ncontract VAIControllerStorageG1 is VAIUnitrollerAdminStorage {\n ComptrollerInterface public comptroller;\n\n struct VenusVAIState {\n /// @notice The last updated venusVAIMintIndex\n uint224 index;\n /// @notice The block number the index was last updated at\n uint32 block;\n }\n\n /// @notice The Venus VAI state\n VenusVAIState public venusVAIState;\n\n /// @notice The Venus VAI state initialized\n bool public isVenusVAIInitialized;\n\n /// @notice The Venus VAI minter index as of the last time they accrued XVS\n mapping(address => uint256) public venusVAIMinterIndex;\n}\n\ncontract VAIControllerStorageG2 is VAIControllerStorageG1 {\n /// @notice Treasury Guardian address\n address public treasuryGuardian;\n\n /// @notice Treasury address\n address public treasuryAddress;\n\n /// @notice Fee percent of accrued interest with decimal 18\n uint256 public treasuryPercent;\n\n /// @notice Guard variable for re-entrancy checks\n bool internal _notEntered;\n\n /// @notice The base rate for stability fee\n uint256 public baseRateMantissa;\n\n /// @notice The float rate for stability fee\n uint256 public floatRateMantissa;\n\n /// @notice The address for VAI interest receiver\n address public receiver;\n\n /// @notice Accumulator of the total earned interest rate since the opening of the market. For example: 0.6 (60%)\n uint256 public vaiMintIndex;\n\n /// @notice Block number that interest was last accrued at\n uint256 internal accrualBlockNumber;\n\n /// @notice Global vaiMintIndex as of the most recent balance-changing action for user\n mapping(address => uint256) internal vaiMinterInterestIndex;\n\n /// @notice Tracks the amount of mintedVAI of a user that represents the accrued interest\n mapping(address => uint256) public pastVAIInterest;\n\n /// @notice VAI mint cap\n uint256 public mintCap;\n\n /// @notice Access control manager address\n address public accessControl;\n}\n\ncontract VAIControllerStorageG3 is VAIControllerStorageG2 {\n /// @notice The address of the prime contract. It can be a ZERO address\n address public prime;\n\n /// @notice Tracks if minting is enabled only for prime token holders. Only used if prime is set\n bool public mintEnabledOnlyForPrimeHolder;\n}\n\ncontract VAIControllerStorageG4 is VAIControllerStorageG3 {\n /// @notice The address of the VAI token\n address internal vai;\n}\n" + }, + "contracts/Tokens/VAI/VAIUnitroller.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/ErrorReporter.sol\";\nimport \"./VAIControllerStorage.sol\";\n\n/**\n * @title VAI Unitroller\n * @author Venus\n * @notice This is the proxy contract for the VAIComptroller\n */\ncontract VAIUnitroller is VAIUnitrollerAdminStorage, VAIControllerErrorReporter {\n /**\n * @notice Emitted when pendingVAIControllerImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingVAIControllerImplementation is accepted, which means comptroller implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor() public {\n // Set admin to caller\n admin = msg.sender;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public returns (uint256) {\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK);\n }\n\n address oldPendingImplementation = pendingVAIControllerImplementation;\n\n pendingVAIControllerImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingVAIControllerImplementation);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts new implementation of comptroller. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public returns (uint256) {\n // Check caller is pendingImplementation\n if (msg.sender != pendingVAIControllerImplementation) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldImplementation = vaiControllerImplementation;\n address oldPendingImplementation = pendingVAIControllerImplementation;\n\n vaiControllerImplementation = pendingVAIControllerImplementation;\n\n pendingVAIControllerImplementation = address(0);\n\n emit NewImplementation(oldImplementation, vaiControllerImplementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingVAIControllerImplementation);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public returns (uint256) {\n // Check caller = admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK);\n }\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint256 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public returns (uint256) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint256(Error.NO_ERROR);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = vaiControllerImplementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/Tokens/VRT/VRT.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/Tokenlock.sol\";\n\ncontract VRT is Tokenlock {\n /// @notice BEP-20 token name for this token\n string public constant name = \"Venus Reward Token\";\n\n /// @notice BEP-20 token symbol for this token\n string public constant symbol = \"VRT\";\n\n /// @notice BEP-20 token decimals for this token\n uint8 public constant decimals = 18;\n\n /// @notice Total number of tokens in circulation\n uint public constant totalSupply = 30000000000e18; // 30 billion VRT\n\n /// @notice Allowance amounts on behalf of others\n mapping(address => mapping(address => uint96)) internal allowances;\n\n /// @notice Official record of token balances for each account\n mapping(address => uint96) internal balances;\n\n /// @notice A record of each accounts delegate\n mapping(address => address) public delegates;\n\n /// @notice A checkpoint for marking number of votes from a given block\n struct Checkpoint {\n uint32 fromBlock;\n uint96 votes;\n }\n\n /// @notice A record of votes checkpoints for each account, by index\n mapping(address => mapping(uint32 => Checkpoint)) public checkpoints;\n\n /// @notice The number of checkpoints for each account\n mapping(address => uint32) public numCheckpoints;\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation struct used by the contract\n bytes32 public constant DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n /// @notice A record of states for signing / validating signatures\n mapping(address => uint) public nonces;\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /// @notice An event thats emitted when a delegate account's vote balance changes\n event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);\n\n /// @notice The standard BEP-20 transfer event\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /// @notice The standard BEP-20 approval event\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Construct a new VRT token\n * @param account The initial account to grant all the tokens\n */\n constructor(address account) public {\n balances[account] = uint96(totalSupply);\n emit Transfer(address(0), account, totalSupply);\n }\n\n /**\n * @notice Get the number of tokens `spender` is approved to spend on behalf of `account`\n * @param account The address of the account holding the funds\n * @param spender The address of the account spending the funds\n * @return The number of tokens approved\n */\n function allowance(address account, address spender) external view returns (uint) {\n return allowances[account][spender];\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint rawAmount) external validLock returns (bool) {\n uint96 amount;\n if (rawAmount == uint(-1)) {\n amount = uint96(-1);\n } else {\n amount = safe96(rawAmount, \"VRT::approve: amount exceeds 96 bits\");\n }\n\n allowances[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @notice Get the number of tokens held by the `account`\n * @param account The address of the account to get the balance of\n * @return The number of tokens held\n */\n function balanceOf(address account) external view returns (uint) {\n return balances[account];\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint rawAmount) external validLock returns (bool) {\n uint96 amount = safe96(rawAmount, \"VRT::transfer: amount exceeds 96 bits\");\n _transferTokens(msg.sender, dst, amount);\n return true;\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint rawAmount) external validLock returns (bool) {\n address spender = msg.sender;\n uint96 spenderAllowance = allowances[src][spender];\n uint96 amount = safe96(rawAmount, \"VRT::approve: amount exceeds 96 bits\");\n\n if (spender != src && spenderAllowance != uint96(-1)) {\n uint96 newAllowance = sub96(\n spenderAllowance,\n amount,\n \"VRT::transferFrom: transfer amount exceeds spender allowance\"\n );\n allowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n }\n\n _transferTokens(src, dst, amount);\n return true;\n }\n\n /**\n * @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The address to delegate votes to\n */\n function delegate(address delegatee) public validLock {\n return _delegate(msg.sender, delegatee);\n }\n\n /**\n * @notice Delegates votes from signatory to `delegatee`\n * @param delegatee The address to delegate votes to\n * @param nonce The contract state required to match the signature\n * @param expiry The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public validLock {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"VRT::delegateBySig: invalid signature\");\n require(nonce == nonces[signatory]++, \"VRT::delegateBySig: invalid nonce\");\n require(now <= expiry, \"VRT::delegateBySig: signature expired\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Gets the current votes balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for `account`\n */\n function getCurrentVotes(address account) external view returns (uint96) {\n uint32 nCheckpoints = numCheckpoints[account];\n return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n /**\n * @notice Determine the prior number of votes for an account as of a block number\n * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.\n * @param account The address of the account to check\n * @param blockNumber The block number to get the vote balance at\n * @return The number of votes the account had as of the given block\n */\n function getPriorVotes(address account, uint blockNumber) public view returns (uint96) {\n require(blockNumber < block.number, \"VRT::getPriorVotes: not yet determined\");\n\n uint32 nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n }\n\n // First check most recent balance\n if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {\n return checkpoints[account][nCheckpoints - 1].votes;\n }\n\n // Next check implicit zero balance\n if (checkpoints[account][0].fromBlock > blockNumber) {\n return 0;\n }\n\n uint32 lower = 0;\n uint32 upper = nCheckpoints - 1;\n while (upper > lower) {\n uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n Checkpoint memory cp = checkpoints[account][center];\n if (cp.fromBlock == blockNumber) {\n return cp.votes;\n } else if (cp.fromBlock < blockNumber) {\n lower = center;\n } else {\n upper = center - 1;\n }\n }\n return checkpoints[account][lower].votes;\n }\n\n function _delegate(address delegator, address delegatee) internal {\n address currentDelegate = delegates[delegator];\n uint96 delegatorBalance = balances[delegator];\n delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _transferTokens(address src, address dst, uint96 amount) internal {\n require(src != address(0), \"VRT::_transferTokens: cannot transfer from the zero address\");\n require(dst != address(0), \"VRT::_transferTokens: cannot transfer to the zero address\");\n\n balances[src] = sub96(balances[src], amount, \"VRT::_transferTokens: transfer amount exceeds balance\");\n balances[dst] = add96(balances[dst], amount, \"VRT::_transferTokens: transfer amount overflows\");\n emit Transfer(src, dst, amount);\n\n _moveDelegates(delegates[src], delegates[dst], amount);\n }\n\n function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {\n if (srcRep != dstRep && amount > 0) {\n if (srcRep != address(0)) {\n uint32 srcRepNum = numCheckpoints[srcRep];\n uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n uint96 srcRepNew = sub96(srcRepOld, amount, \"VRT::_moveVotes: vote amount underflows\");\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint96 dstRepNew = add96(dstRepOld, amount, \"VRT::_moveVotes: vote amount overflows\");\n _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {\n uint32 blockNumber = safe32(block.number, \"VRT::_writeCheckpoint: block number exceeds 32 bits\");\n\n if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {\n checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n } else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);\n numCheckpoints[delegatee] = nCheckpoints + 1;\n }\n\n emit DelegateVotesChanged(delegatee, oldVotes, newVotes);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n < 2 ** 32, errorMessage);\n return uint32(n);\n }\n\n function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {\n require(n < 2 ** 96, errorMessage);\n return uint96(n);\n }\n\n function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n uint96 c = a + b;\n require(c >= a, errorMessage);\n return c;\n }\n\n function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n function getChainId() internal pure returns (uint) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n return chainId;\n }\n}\n" + }, + "contracts/Tokens/VRT/VRTConverter.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/IBEP20.sol\";\nimport \"../../Utils/SafeBEP20.sol\";\nimport \"../XVS/IXVSVesting.sol\";\nimport \"./VRTConverterStorage.sol\";\nimport \"./VRTConverterProxy.sol\";\n\n/**\n * @title Venus's VRTConversion Contract\n * @author Venus\n */\ncontract VRTConverter is VRTConverterStorage {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n address public constant DEAD_ADDRESS = 0x000000000000000000000000000000000000dEaD;\n\n /// @notice decimal precision for VRT\n uint256 public constant vrtDecimalsMultiplier = 1e18;\n\n /// @notice decimal precision for XVS\n uint256 public constant xvsDecimalsMultiplier = 1e18;\n\n /// @notice Emitted when an admin set conversion info\n event ConversionInfoSet(\n uint256 conversionRatio,\n uint256 conversionStartTime,\n uint256 conversionPeriod,\n uint256 conversionEndTime\n );\n\n /// @notice Emitted when token conversion is done\n event TokenConverted(\n address reedeemer,\n address vrtAddress,\n uint256 vrtAmount,\n address xvsAddress,\n uint256 xvsAmount\n );\n\n /// @notice Emitted when an admin withdraw converted token\n event TokenWithdraw(address token, address to, uint256 amount);\n\n /// @notice Emitted when XVSVestingAddress is set\n event XVSVestingSet(address xvsVestingAddress);\n\n constructor() public {}\n\n function initialize(\n address _vrtAddress,\n address _xvsAddress,\n uint256 _conversionRatio,\n uint256 _conversionStartTime,\n uint256 _conversionPeriod\n ) public {\n require(msg.sender == admin, \"only admin may initialize the VRTConverter\");\n require(initialized == false, \"VRTConverter is already initialized\");\n\n require(_vrtAddress != address(0), \"vrtAddress cannot be Zero\");\n vrt = IBEP20(_vrtAddress);\n\n require(_xvsAddress != address(0), \"xvsAddress cannot be Zero\");\n xvs = IBEP20(_xvsAddress);\n\n require(_conversionRatio > 0, \"conversionRatio cannot be Zero\");\n conversionRatio = _conversionRatio;\n\n require(_conversionStartTime >= block.timestamp, \"conversionStartTime must be time in the future\");\n require(_conversionPeriod > 0, \"_conversionPeriod is invalid\");\n\n conversionStartTime = _conversionStartTime;\n conversionPeriod = _conversionPeriod;\n conversionEndTime = conversionStartTime.add(conversionPeriod);\n emit ConversionInfoSet(conversionRatio, conversionStartTime, conversionPeriod, conversionEndTime);\n\n totalVrtConverted = 0;\n _notEntered = true;\n initialized = true;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n /**\n * @notice sets XVSVestingProxy Address\n * @dev Note: If XVSVestingProxy is not set, then Conversion is not allowed\n * @param _xvsVestingAddress The XVSVestingProxy Address\n */\n function setXVSVesting(address _xvsVestingAddress) public {\n require(msg.sender == admin, \"only admin may initialize the Vault\");\n require(_xvsVestingAddress != address(0), \"xvsVestingAddress cannot be Zero\");\n xvsVesting = IXVSVesting(_xvsVestingAddress);\n emit XVSVestingSet(_xvsVestingAddress);\n }\n\n modifier isInitialized() {\n require(initialized == true, \"VRTConverter is not initialized\");\n _;\n }\n\n function isConversionActive() public view returns (bool) {\n uint256 currentTime = block.timestamp;\n if (currentTime >= conversionStartTime && currentTime <= conversionEndTime) {\n return true;\n }\n return false;\n }\n\n modifier checkForActiveConversionPeriod() {\n uint256 currentTime = block.timestamp;\n require(currentTime >= conversionStartTime, \"Conversion did not start yet\");\n require(currentTime <= conversionEndTime, \"Conversion Period Ended\");\n _;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n /**\n * @notice Transfer VRT and redeem XVS\n * @dev Note: If there is not enough XVS, we do not perform the conversion.\n * @param vrtAmount The amount of VRT\n */\n function convert(uint256 vrtAmount) external isInitialized checkForActiveConversionPeriod nonReentrant {\n require(\n address(xvsVesting) != address(0) && address(xvsVesting) != DEAD_ADDRESS,\n \"XVS-Vesting Address is not set\"\n );\n require(vrtAmount > 0, \"VRT amount must be non-zero\");\n totalVrtConverted = totalVrtConverted.add(vrtAmount);\n\n uint256 redeemAmount = vrtAmount.mul(conversionRatio).mul(xvsDecimalsMultiplier).div(1e18).div(\n vrtDecimalsMultiplier\n );\n\n emit TokenConverted(msg.sender, address(vrt), vrtAmount, address(xvs), redeemAmount);\n vrt.safeTransferFrom(msg.sender, DEAD_ADDRESS, vrtAmount);\n xvsVesting.deposit(msg.sender, redeemAmount);\n }\n\n /*** Admin Functions ***/\n function _become(VRTConverterProxy vrtConverterProxy) public {\n require(msg.sender == vrtConverterProxy.admin(), \"only proxy admin can change brains\");\n vrtConverterProxy._acceptImplementation();\n }\n}\n" + }, + "contracts/Tokens/VRT/VRTConverterProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VRTConverterStorage.sol\";\n\ncontract VRTConverterProxy is VRTConverterAdminStorage {\n /**\n * @notice Emitted when pendingImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingImplementation is accepted, which means VRTConverter implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor(\n address implementation_,\n address _vrtAddress,\n address _xvsAddress,\n uint256 _conversionRatio,\n uint256 _conversionStartTime,\n uint256 _conversionPeriod\n ) public nonZeroAddress(implementation_) nonZeroAddress(_vrtAddress) nonZeroAddress(_xvsAddress) {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_);\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(\n implementation_,\n abi.encodeWithSignature(\n \"initialize(address,address,uint256,uint256,uint256)\",\n _vrtAddress,\n _xvsAddress,\n _conversionRatio,\n _conversionStartTime,\n _conversionPeriod\n )\n );\n }\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n */\n function _setImplementation(address implementation_) public {\n require(msg.sender == admin, \"VRTConverterProxy::_setImplementation: admin only\");\n require(implementation_ != address(0), \"VRTConverterProxy::_setImplementation: invalid implementation address\");\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal nonZeroAddress(callee) returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(\n address newPendingImplementation\n ) public nonZeroAddress(newPendingImplementation) {\n require(msg.sender == admin, \"Only admin can set Pending Implementation\");\n\n address oldPendingImplementation = pendingImplementation;\n\n pendingImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Accepts new implementation of VRTConverter. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @dev return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public {\n // Check caller is pendingImplementation\n require(\n msg.sender == pendingImplementation,\n \"only address marked as pendingImplementation can accept Implementation\"\n );\n\n // Save current values for inclusion in log\n address oldImplementation = implementation;\n address oldPendingImplementation = pendingImplementation;\n\n implementation = pendingImplementation;\n\n pendingImplementation = address(0);\n\n emit NewImplementation(oldImplementation, implementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @dev return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public nonZeroAddress(newPendingAdmin) {\n // Check caller = admin\n require(msg.sender == admin, \"only admin can set pending admin\");\n require(newPendingAdmin != pendingAdmin, \"New pendingAdmin can not be same as the previous one\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @dev return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public {\n // Check caller is pendingAdmin\n require(msg.sender == pendingAdmin, \"only address marked as pendingAdmin can accept as Admin\");\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/Tokens/VRT/VRTConverterStorage.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/SafeMath.sol\";\nimport \"../../Utils/IBEP20.sol\";\nimport \"../XVS/IXVSVesting.sol\";\n\ncontract VRTConverterAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of VRTConverter\n */\n address public implementation;\n\n /**\n * @notice Pending brains of VRTConverter\n */\n address public pendingImplementation;\n}\n\ncontract VRTConverterStorage is VRTConverterAdminStorage {\n /// @notice Guard variable for re-entrancy checks\n bool public _notEntered;\n\n /// @notice indicator to check if the contract is initialized\n bool public initialized;\n\n /// @notice The VRT TOKEN!\n IBEP20 public vrt;\n\n /// @notice The XVS TOKEN!\n IBEP20 public xvs;\n\n /// @notice XVSVesting Contract reference\n IXVSVesting public xvsVesting;\n\n /// @notice Conversion ratio from VRT to XVS with decimal 18\n uint256 public conversionRatio;\n\n /// @notice total VRT converted to XVS\n uint256 public totalVrtConverted;\n\n /// @notice Conversion Start time in EpochSeconds\n uint256 public conversionStartTime;\n\n /// @notice ConversionPeriod in Seconds\n uint256 public conversionPeriod;\n\n /// @notice Conversion End time in EpochSeconds\n uint256 public conversionEndTime;\n}\n" + }, + "contracts/Tokens/VTokens/VBep20.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport { VToken, VBep20Interface, ComptrollerInterface, InterestRateModel, VTokenInterface } from \"./VToken.sol\";\nimport { EIP20Interface } from \"../EIP20Interface.sol\";\nimport { EIP20NonStandardInterface } from \"../EIP20NonStandardInterface.sol\";\n\n/**\n * @title Venus's VBep20 Contract\n * @notice vTokens which wrap an EIP-20 underlying\n * @author Venus\n */\ncontract VBep20 is VToken, VBep20Interface {\n /*** User Interface ***/\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Transfer event\n // @custom:event Emits Mint event\n function mint(uint mintAmount) external returns (uint) {\n (uint err, ) = mintInternal(mintAmount);\n return err;\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param receiver The account which is receiving the vTokens\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Transfer event\n // @custom:event Emits MintBehalf event\n function mintBehalf(address receiver, uint mintAmount) external returns (uint) {\n (uint err, ) = mintBehalfInternal(receiver, mintAmount);\n return err;\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeem(uint redeemTokens) external returns (uint) {\n return redeemInternal(msg.sender, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems assets on behalf of some other address. This function is only available\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemer The user on behalf of whom to redeem\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemBehalf(address redeemer, uint redeemTokens) external returns (uint) {\n require(comptroller.approvedDelegates(redeemer, msg.sender), \"not an approved delegate\");\n\n return redeemInternal(redeemer, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n return redeemUnderlyingInternal(msg.sender, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemer, on behalf of whom to redeem\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemUnderlyingBehalf(address redeemer, uint redeemAmount) external returns (uint) {\n require(comptroller.approvedDelegates(redeemer, msg.sender), \"not an approved delegate\");\n\n return redeemUnderlyingInternal(redeemer, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Borrow event on success\n function borrow(uint borrowAmount) external returns (uint) {\n return borrowInternal(msg.sender, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender borrows assets on behalf of some other address. This function is only available\n * for senders, explicitly marked as delegates of the borrower using `comptroller.updateDelegate`\n * @param borrower The borrower, on behalf of whom to borrow.\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Borrow event on success\n function borrowBehalf(address borrower, uint borrowAmount) external returns (uint) {\n require(comptroller.approvedDelegates(borrower, msg.sender), \"not an approved delegate\");\n return borrowInternal(borrower, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrow(uint repayAmount) external returns (uint) {\n (uint err, ) = repayBorrowInternal(repayAmount);\n return err;\n }\n\n /**\n * @notice Sender repays a borrow belonging to another borrowing account\n * @param borrower The account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) {\n (uint err, ) = repayBorrowBehalfInternal(borrower, repayAmount);\n return err;\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emit LiquidateBorrow event on success\n function liquidateBorrow(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint) {\n (uint err, ) = liquidateBorrowInternal(borrower, repayAmount, vTokenCollateral);\n return err;\n }\n\n /**\n * @notice The sender adds to reserves.\n * @param addAmount The amount of underlying tokens to add as reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits ReservesAdded event\n function _addReserves(uint addAmount) external returns (uint) {\n return _addReservesInternal(addAmount);\n }\n\n /**\n * @notice Initialize the new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n */\n function initialize(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) public {\n // VToken initialize does the bulk of the work\n super.initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_);\n\n // Set underlying and sanity check it\n underlying = underlying_;\n EIP20Interface(underlying).totalSupply();\n }\n\n /*** Safe Token ***/\n\n /**\n * @dev Similar to EIP20 transfer, except it handles a False result from `transferFrom` and reverts in that case.\n * This will revert due to insufficient balance or insufficient allowance.\n * This function returns the actual amount received,\n * which may be less than `amount` if there is a fee attached to the transfer.\n *\n * Note: This wrapper safely handles non-standard BEP-20 tokens that do not return a value.\n * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\n function doTransferIn(address from, uint amount) internal returns (uint) {\n uint balanceBefore = EIP20Interface(underlying).balanceOf(address(this));\n EIP20NonStandardInterface(underlying).transferFrom(from, address(this), amount);\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a compliant BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n require(success, \"TOKEN_TRANSFER_IN_FAILED\");\n\n // Calculate the amount that was *actually* transferred\n uint balanceAfter = EIP20Interface(underlying).balanceOf(address(this));\n require(balanceAfter >= balanceBefore, \"TOKEN_TRANSFER_IN_OVERFLOW\");\n return balanceAfter - balanceBefore; // underflow already checked above, just subtract\n }\n\n /**\n * @dev Similar to EIP20 transfer, except it handles a False success from `transfer` and returns an explanatory\n * error code rather than reverting. If caller has not called checked protocol's balance, this may revert due to\n * insufficient cash held in this contract. If caller has checked protocol's balance prior to this call, and verified\n * it is >= amount, this should not revert in normal conditions.\n *\n * Note: This wrapper safely handles non-standard BEP-20 tokens that do not return a value.\n * See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca\n */\n function doTransferOut(address payable to, uint amount) internal {\n EIP20NonStandardInterface(underlying).transfer(to, amount);\n\n bool success;\n assembly {\n switch returndatasize()\n case 0 {\n // This is a non-standard BEP-20\n success := not(0) // set success to true\n }\n case 32 {\n // This is a compliant BEP-20\n returndatacopy(0, 0, 32)\n success := mload(0) // Set `success = returndata` of external call\n }\n default {\n // This is an excessively non-compliant BEP-20, revert.\n revert(0, 0)\n }\n }\n require(success, \"TOKEN_TRANSFER_OUT_FAILED\");\n }\n\n /**\n * @notice Gets balance of this contract in terms of the underlying\n * @dev This excludes the value of the current message, if any\n * @return The quantity of underlying tokens owned by this contract\n */\n function getCashPrior() internal view returns (uint) {\n return EIP20Interface(underlying).balanceOf(address(this));\n }\n}\n" + }, + "contracts/Tokens/VTokens/VBep20Delegate.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport { VBep20 } from \"./VBep20.sol\";\nimport { VDelegateInterface } from \"./VTokenInterfaces.sol\";\n\n/**\n * @title Venus's VBep20Delegate Contract\n * @notice VTokens which wrap an EIP-20 underlying and are delegated to\n * @author Venus\n */\ncontract VBep20Delegate is VBep20, VDelegateInterface {\n /**\n * @notice Construct an empty delegate\n */\n constructor() public {}\n\n /**\n * @notice Called by the delegator on a delegate to initialize it for duty\n * @param data The encoded bytes data for any initialization\n */\n function _becomeImplementation(bytes memory data) public {\n // Shh -- currently unused\n data;\n\n // Shh -- we don't ever want this hook to be marked pure\n if (false) {\n implementation = address(0);\n }\n\n require(msg.sender == admin, \"only the admin may call _becomeImplementation\");\n }\n\n /**\n * @notice Called by the delegator on a delegate to forfeit its responsibility\n */\n function _resignImplementation() public {\n // Shh -- we don't ever want this hook to be marked pure\n if (false) {\n implementation = address(0);\n }\n\n require(msg.sender == admin, \"only the admin may call _resignImplementation\");\n }\n}\n" + }, + "contracts/Tokens/VTokens/VBep20Delegator.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VTokenInterfaces.sol\";\n\n/**\n * @title Venus's VBep20Delegator Contract\n * @notice vTokens which wrap an EIP-20 underlying and delegate to an implementation\n * @author Venus\n */\ncontract VBep20Delegator is VTokenInterface, VBep20Interface, VDelegatorInterface {\n /**\n * @notice Construct a new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n * @param implementation_ The address of the implementation the contract delegates to\n * @param becomeImplementationData The encoded args for becomeImplementation\n */\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_,\n address implementation_,\n bytes memory becomeImplementationData\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(\n implementation_,\n abi.encodeWithSignature(\n \"initialize(address,address,address,uint256,string,string,uint8)\",\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_\n )\n );\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_, false, becomeImplementationData);\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n\n /**\n * @notice Delegates execution to an implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n */\n function() external payable {\n require(msg.value == 0, \"VBep20Delegator:fallback: cannot send value to fallback\");\n\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function mint(uint mintAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"mint(uint256)\", mintAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function mintBehalf(address receiver, uint mintAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"mintBehalf(address,uint256)\", receiver, mintAmount)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying asset\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function redeem(uint redeemTokens) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"redeem(uint256)\", redeemTokens));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"redeemUnderlying(uint256)\", redeemAmount)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function borrow(uint borrowAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrow(uint256)\", borrowAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function repayBorrow(uint repayAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"repayBorrow(uint256)\", repayAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sender repays a borrow belonging to another borrower\n * @param borrower The account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"repayBorrowBehalf(address,uint256)\", borrower, repayAmount)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function liquidateBorrow(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"liquidateBorrow(address,uint256,address)\", borrower, repayAmount, vTokenCollateral)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint amount) external returns (bool) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"transfer(address,uint256)\", dst, amount));\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"transferFrom(address,address,uint256)\", src, dst, amount)\n );\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved (-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint256 amount) external returns (bool) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"approve(address,uint256)\", spender, amount)\n );\n return abi.decode(data, (bool));\n }\n\n /**\n * @notice Get the underlying balance of the `owner`\n * @dev This also accrues interest in a transaction\n * @param owner The address of the account to query\n * @return The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"balanceOfUnderlying(address)\", owner));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return The total borrows with interest\n */\n function totalBorrowsCurrent() external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"totalBorrowsCurrent()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\n * @param account The address whose balance should be calculated after updating borrowIndex\n * @return The calculated balance\n */\n function borrowBalanceCurrent(address account) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"borrowBalanceCurrent(address)\", account));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Transfers collateral tokens (this market) to the liquidator.\n * @dev Will fail unless called by another vToken during the process of liquidation.\n * It's absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\n * @param liquidator The account receiving seized collateral\n * @param borrower The account having collateral seized\n * @param seizeTokens The number of vTokens to seize\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"seize(address,address,uint256)\", liquidator, borrower, seizeTokens)\n );\n return abi.decode(data, (uint));\n }\n\n /*** Admin Functions ***/\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setPendingAdmin(address)\", newPendingAdmin)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh\n * @dev Admin function to accrue interest and set a new reserve factor\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setReserveFactor(uint256)\", newReserveFactorMantissa)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accepts transfer of admin rights. `msg.sender` must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _acceptAdmin() external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_acceptAdmin()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrues interest and adds reserves by transferring from admin\n * @param addAmount Amount of reserves to add\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _addReserves(uint addAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_addReserves(uint256)\", addAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to admin\n * @param reduceAmount Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _reduceReserves(uint reduceAmount) external returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"_reduceReserves(uint256)\", reduceAmount));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return The quantity of underlying asset owned by this contract\n */\n function getCash() external view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"getCash()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return The number of tokens allowed to be spent (-1 means infinite)\n */\n function allowance(address owner, address spender) external view returns (uint) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"allowance(address,address)\", owner, spender)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Get the token balance of the `owner`\n * @param owner The address of the account to query\n * @return The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"balanceOf(address)\", owner));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Get a snapshot of the account's balances and the cached exchange rate\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\n * @param account Address of the account to snapshot\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\n */\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"getAccountSnapshot(address)\", account)\n );\n return abi.decode(data, (uint, uint, uint, uint));\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"borrowRatePerBlock()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this vToken\n * @return The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"supplyRatePerBlock()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\n */\n // @custom:access Only callable by admin\n function _setImplementation(\n address implementation_,\n bool allowResign,\n bytes memory becomeImplementationData\n ) public {\n require(msg.sender == admin, \"VBep20Delegator::_setImplementation: Caller must be admin\");\n\n if (allowResign) {\n delegateToImplementation(abi.encodeWithSignature(\"_resignImplementation()\"));\n }\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n delegateToImplementation(abi.encodeWithSignature(\"_becomeImplementation(bytes)\", becomeImplementationData));\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"exchangeRateCurrent()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Applies accrued interest to total borrows and reserves.\n * @dev This calculates interest accrued from the last checkpointed block\n * up to the current block and writes new checkpoint to storage.\n */\n function accrueInterest() public returns (uint) {\n bytes memory data = delegateToImplementation(abi.encodeWithSignature(\"accrueInterest()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Sets a new comptroller for the market\n * @dev Admin function to set a new comptroller\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setComptroller(address)\", newComptroller)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Accrues interest and updates the interest rate model using `_setInterestRateModelFresh`\n * @dev Admin function to accrue interest and update the interest rate model\n * @param newInterestRateModel The new interest rate model to use\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint) {\n bytes memory data = delegateToImplementation(\n abi.encodeWithSignature(\"_setInterestRateModel(address)\", newInterestRateModel)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Delegates execution to the implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateToImplementation(bytes memory data) public returns (bytes memory) {\n return delegateTo(implementation, data);\n }\n\n /**\n * @notice Delegates execution to an implementation contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * There are an additional 2 prefix uints from the wrapper returndata, which we ignore since we make an extra hop.\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateToViewImplementation(bytes memory data) public view returns (bytes memory) {\n (bool success, bytes memory returnData) = address(this).staticcall(\n abi.encodeWithSignature(\"delegateToImplementation(bytes)\", data)\n );\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return abi.decode(returnData, (bytes));\n }\n\n /**\n * @notice Return the borrow balance of account based on stored data\n * @param account The address whose balance should be calculated\n * @return The calculated balance\n */\n function borrowBalanceStored(address account) public view returns (uint) {\n bytes memory data = delegateToViewImplementation(\n abi.encodeWithSignature(\"borrowBalanceStored(address)\", account)\n );\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Calculates the exchange rate from the underlying to the VToken\n * @dev This function does not accrue interest before calculating the exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() public view returns (uint) {\n bytes memory data = delegateToViewImplementation(abi.encodeWithSignature(\"exchangeRateStored()\"));\n return abi.decode(data, (uint));\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n}\n" + }, + "contracts/Tokens/VTokens/VBep20Immutable.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VBep20.sol\";\n\n/**\n * @title Venus's VBep20Immutable Contract\n * @notice VTokens which wrap an EIP-20 underlying and are immutable\n * @author Venus\n */\ncontract VBep20Immutable is VBep20 {\n /**\n * @notice Construct a new money market\n * @param underlying_ The address of the underlying asset\n * @param comptroller_ The address of the comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n */\n constructor(\n address underlying_,\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // Initialize the market\n initialize(\n underlying_,\n comptroller_,\n interestRateModel_,\n initialExchangeRateMantissa_,\n name_,\n symbol_,\n decimals_\n );\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n}\n" + }, + "contracts/Tokens/VTokens/VBNB.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VToken.sol\";\n\n/**\n * @title Venus's vBNB Contract\n * @notice vToken which wraps BNB\n * @author Venus\n */\ncontract VBNB is VToken {\n /**\n * @notice Construct a new vBNB money market\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ BEP-20 name of this token\n * @param symbol_ BEP-20 symbol of this token\n * @param decimals_ BEP-20 decimal precision of this token\n * @param admin_ Address of the administrator of this token\n */\n constructor(\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_,\n address payable admin_\n ) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n initialize(comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, decimals_);\n\n // Set the proper admin now that initialization is done\n admin = admin_;\n }\n\n /**\n * @notice Send BNB to VBNB to mint\n */\n function() external payable {\n (uint err, ) = mintInternal(msg.value);\n requireNoError(err, \"mint failed\");\n }\n\n /*** User Interface ***/\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Reverts upon any failure\n */\n // @custom:event Emits Transfer event\n // @custom:event Emits Mint event\n function mint() external payable {\n (uint err, ) = mintInternal(msg.value);\n requireNoError(err, \"mint failed\");\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for the underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeem(uint redeemTokens) external returns (uint) {\n return redeemInternal(msg.sender, msg.sender, redeemTokens);\n }\n\n /**\n * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemAmount The amount of underlying to redeem\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Redeem event on success\n // @custom:event Emits Transfer event on success\n // @custom:event Emits RedeemFee when fee is charged by the treasury\n function redeemUnderlying(uint redeemAmount) external returns (uint) {\n return redeemUnderlyingInternal(msg.sender, msg.sender, redeemAmount);\n }\n\n /**\n * @notice Sender borrows assets from the protocol to their own address\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Borrow event on success\n function borrow(uint borrowAmount) external returns (uint) {\n return borrowInternal(msg.sender, msg.sender, borrowAmount);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @dev Reverts upon any failure\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrow() external payable {\n (uint err, ) = repayBorrowInternal(msg.value);\n requireNoError(err, \"repayBorrow failed\");\n }\n\n /**\n * @notice Sender repays a borrow belonging to borrower\n * @dev Reverts upon any failure\n * @param borrower The account with the debt being payed off\n */\n // @custom:event Emits RepayBorrow event on success\n function repayBorrowBehalf(address borrower) external payable {\n (uint err, ) = repayBorrowBehalfInternal(borrower, msg.value);\n requireNoError(err, \"repayBorrowBehalf failed\");\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @dev Reverts upon any failure\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n */\n // @custom:event Emit LiquidateBorrow event on success\n function liquidateBorrow(address borrower, VToken vTokenCollateral) external payable {\n (uint err, ) = liquidateBorrowInternal(borrower, msg.value, vTokenCollateral);\n requireNoError(err, \"liquidateBorrow failed\");\n }\n\n /*** Safe Token ***/\n\n /**\n * @notice Perform the actual transfer in, which is a no-op\n * @param from Address sending the BNB\n * @param amount Amount of BNB being sent\n * @return The actual amount of BNB transferred\n */\n function doTransferIn(address from, uint amount) internal returns (uint) {\n // Sanity checks\n require(msg.sender == from, \"sender mismatch\");\n require(msg.value == amount, \"value mismatch\");\n return amount;\n }\n\n function doTransferOut(address payable to, uint amount) internal {\n /* Send the BNB, with minimal gas and revert on failure */\n to.transfer(amount);\n }\n\n /**\n * @notice Gets balance of this contract in terms of BNB, before this message\n * @dev This excludes the value of the current message, if any\n * @return The quantity of BNB owned by this contract\n */\n function getCashPrior() internal view returns (uint) {\n (MathError err, uint startingBalance) = subUInt(address(this).balance, msg.value);\n require(err == MathError.NO_ERROR, \"cash prior math error\");\n return startingBalance;\n }\n\n function requireNoError(uint errCode, string memory message) internal pure {\n if (errCode == uint(Error.NO_ERROR)) {\n return;\n }\n\n bytes memory fullMessage = new bytes(bytes(message).length + 5);\n uint i;\n\n for (i = 0; i < bytes(message).length; i++) {\n fullMessage[i] = bytes(message)[i];\n }\n\n fullMessage[i + 0] = bytes1(uint8(32));\n fullMessage[i + 1] = bytes1(uint8(40));\n fullMessage[i + 2] = bytes1(uint8(48 + (errCode / 10)));\n fullMessage[i + 3] = bytes1(uint8(48 + (errCode % 10)));\n fullMessage[i + 4] = bytes1(uint8(41));\n\n require(errCode == uint(Error.NO_ERROR), string(fullMessage));\n }\n}\n" + }, + "contracts/Tokens/VTokens/VToken.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Comptroller/ComptrollerInterface.sol\";\nimport \"../../Utils/ErrorReporter.sol\";\nimport \"../../Utils/Exponential.sol\";\nimport \"../../Tokens/EIP20Interface.sol\";\nimport \"../../Tokens/EIP20NonStandardInterface.sol\";\nimport \"../../InterestRateModels/InterestRateModel.sol\";\nimport \"./VTokenInterfaces.sol\";\nimport { IAccessControlManagerV5 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV5.sol\";\n\n/**\n * @title Venus's vToken Contract\n * @notice Abstract base for vTokens\n * @author Venus\n */\ncontract VToken is VTokenInterface, Exponential, TokenErrorReporter {\n struct MintLocalVars {\n MathError mathErr;\n uint exchangeRateMantissa;\n uint mintTokens;\n uint totalSupplyNew;\n uint accountTokensNew;\n uint actualMintAmount;\n }\n\n struct RedeemLocalVars {\n MathError mathErr;\n uint exchangeRateMantissa;\n uint redeemTokens;\n uint redeemAmount;\n uint totalSupplyNew;\n uint accountTokensNew;\n }\n\n struct BorrowLocalVars {\n MathError mathErr;\n uint accountBorrows;\n uint accountBorrowsNew;\n uint totalBorrowsNew;\n }\n\n struct RepayBorrowLocalVars {\n Error err;\n MathError mathErr;\n uint repayAmount;\n uint borrowerIndex;\n uint accountBorrows;\n uint accountBorrowsNew;\n uint totalBorrowsNew;\n uint actualRepayAmount;\n }\n\n /*** Reentrancy Guard ***/\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n // @custom:event Emits Transfer event\n function transfer(address dst, uint256 amount) external nonReentrant returns (bool) {\n return transferTokens(msg.sender, msg.sender, dst, amount) == uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n // @custom:event Emits Transfer event\n function transferFrom(address src, address dst, uint256 amount) external nonReentrant returns (bool) {\n return transferTokens(msg.sender, src, dst, amount) == uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may transfer tokens\n * @param amount The number of tokens that are approved (-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n // @custom:event Emits Approval event on successful approve\n function approve(address spender, uint256 amount) external returns (bool) {\n transferAllowances[msg.sender][spender] = amount;\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @notice Get the underlying balance of the `owner`\n * @dev This also accrues interest in a transaction\n * @param owner The address of the account to query\n * @return The amount of underlying owned by `owner`\n */\n function balanceOfUnderlying(address owner) external returns (uint) {\n Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\n (MathError mErr, uint balance) = mulScalarTruncate(exchangeRate, accountTokens[owner]);\n ensureNoMathError(mErr);\n return balance;\n }\n\n /**\n * @notice Returns the current total borrows plus accrued interest\n * @return The total borrows with interest\n */\n function totalBorrowsCurrent() external nonReentrant returns (uint) {\n require(accrueInterest() == uint(Error.NO_ERROR), \"accrue interest failed\");\n return totalBorrows;\n }\n\n /**\n * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\n * @param account The address whose balance should be calculated after updating borrowIndex\n * @return The calculated balance\n */\n function borrowBalanceCurrent(address account) external nonReentrant returns (uint) {\n require(accrueInterest() == uint(Error.NO_ERROR), \"accrue interest failed\");\n return borrowBalanceStored(account);\n }\n\n /**\n * @notice Transfers collateral tokens (this market) to the liquidator.\n * @dev Will fail unless called by another vToken during the process of liquidation.\n * Its absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\n * @param liquidator The account receiving seized collateral\n * @param borrower The account having collateral seized\n * @param seizeTokens The number of vTokens to seize\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits Transfer event\n function seize(address liquidator, address borrower, uint seizeTokens) external nonReentrant returns (uint) {\n return seizeInternal(msg.sender, liquidator, borrower, seizeTokens);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits NewPendingAdmin event with old and new admin addresses\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint) {\n // Check caller = admin\n ensureAdmin(msg.sender);\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits NewAdmin event on successful acceptance\n // @custom:event Emits NewPendingAdmin event with null new pending admin\n function _acceptAdmin() external returns (uint) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice accrues interest and sets a new reserve factor for the protocol using `_setReserveFactorFresh`\n * @dev Governor function to accrue interest and set a new reserve factor\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits NewReserveFactor event\n function _setReserveFactor(uint newReserveFactorMantissa_) external nonReentrant returns (uint) {\n ensureAllowed(\"_setReserveFactor(uint256)\");\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reserve factor change failed.\n return fail(Error(error), FailureInfo.SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED);\n }\n // _setReserveFactorFresh emits reserve-factor-specific logs on errors, so we don't need to.\n return _setReserveFactorFresh(newReserveFactorMantissa_);\n }\n\n /**\n * @notice Sets the address of the access control manager of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlManagerAddress New address for the access control\n * @return uint 0=success, otherwise will revert\n */\n function setAccessControlManager(address newAccessControlManagerAddress) external returns (uint) {\n // Check caller is admin\n ensureAdmin(msg.sender);\n\n ensureNonZeroAddress(newAccessControlManagerAddress);\n\n emit NewAccessControlManager(accessControlManager, newAccessControlManagerAddress);\n accessControlManager = newAccessControlManagerAddress;\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accrues interest and reduces reserves by transferring to protocol share reserve\n * @param reduceAmount_ Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits ReservesReduced event\n function _reduceReserves(uint reduceAmount_) external nonReentrant returns (uint) {\n ensureAllowed(\"_reduceReserves(uint256)\");\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\n return fail(Error(error), FailureInfo.REDUCE_RESERVES_ACCRUE_INTEREST_FAILED);\n }\n\n // If reserves were reduced in accrueInterest\n if (reduceReservesBlockNumber == block.number) return (uint(Error.NO_ERROR));\n // _reduceReservesFresh emits reserve-reduction-specific logs on errors, so we don't need to.\n return _reduceReservesFresh(reduceAmount_);\n }\n\n /**\n * @notice Get the current allowance from `owner` for `spender`\n * @param owner The address of the account which owns the tokens to be spent\n * @param spender The address of the account which may transfer tokens\n * @return The number of tokens allowed to be spent (-1 means infinite)\n */\n function allowance(address owner, address spender) external view returns (uint256) {\n return transferAllowances[owner][spender];\n }\n\n /**\n * @notice Get the token balance of the `owner`\n * @param owner The address of the account to query\n * @return The number of tokens owned by `owner`\n */\n function balanceOf(address owner) external view returns (uint256) {\n return accountTokens[owner];\n }\n\n /**\n * @notice Get a snapshot of the account's balances, and the cached exchange rate\n * @dev This is used by comptroller to more efficiently perform liquidity checks.\n * @param account Address of the account to snapshot\n * @return (possible error, token balance, borrow balance, exchange rate mantissa)\n */\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint) {\n uint vTokenBalance = accountTokens[account];\n uint borrowBalance;\n uint exchangeRateMantissa;\n\n MathError mErr;\n\n (mErr, borrowBalance) = borrowBalanceStoredInternal(account);\n if (mErr != MathError.NO_ERROR) {\n return (uint(Error.MATH_ERROR), 0, 0, 0);\n }\n\n (mErr, exchangeRateMantissa) = exchangeRateStoredInternal();\n if (mErr != MathError.NO_ERROR) {\n return (uint(Error.MATH_ERROR), 0, 0, 0);\n }\n\n return (uint(Error.NO_ERROR), vTokenBalance, borrowBalance, exchangeRateMantissa);\n }\n\n /**\n * @notice Returns the current per-block supply interest rate for this vToken\n * @return The supply interest rate per block, scaled by 1e18\n */\n function supplyRatePerBlock() external view returns (uint) {\n return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);\n }\n\n /**\n * @notice Returns the current per-block borrow interest rate for this vToken\n * @return The borrow interest rate per block, scaled by 1e18\n */\n function borrowRatePerBlock() external view returns (uint) {\n return interestRateModel.getBorrowRate(getCashPrior(), totalBorrows, totalReserves);\n }\n\n /**\n * @notice Get cash balance of this vToken in the underlying asset\n * @return The quantity of underlying asset owned by this contract\n */\n function getCash() external view returns (uint) {\n return getCashPrior();\n }\n\n /**\n * @notice Governance function to set new threshold of block difference after which funds will be sent to the protocol share reserve\n * @param newReduceReservesBlockDelta_ block difference value\n */\n function setReduceReservesBlockDelta(uint256 newReduceReservesBlockDelta_) external {\n require(newReduceReservesBlockDelta_ > 0, \"Invalid Input\");\n ensureAllowed(\"setReduceReservesBlockDelta(uint256)\");\n emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, newReduceReservesBlockDelta_);\n reduceReservesBlockDelta = newReduceReservesBlockDelta_;\n }\n\n /**\n * @notice Sets protocol share reserve contract address\n * @param protcolShareReserve_ The address of protocol share reserve contract\n */\n function setProtocolShareReserve(address payable protcolShareReserve_) external {\n // Check caller is admin\n ensureAdmin(msg.sender);\n ensureNonZeroAddress(protcolShareReserve_);\n emit NewProtocolShareReserve(protocolShareReserve, protcolShareReserve_);\n protocolShareReserve = protcolShareReserve_;\n }\n\n /**\n * @notice Initialize the money market\n * @param comptroller_ The address of the Comptroller\n * @param interestRateModel_ The address of the interest rate model\n * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\n * @param name_ EIP-20 name of this token\n * @param symbol_ EIP-20 symbol of this token\n * @param decimals_ EIP-20 decimal precision of this token\n */\n function initialize(\n ComptrollerInterface comptroller_,\n InterestRateModel interestRateModel_,\n uint initialExchangeRateMantissa_,\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) public {\n ensureAdmin(msg.sender);\n require(accrualBlockNumber == 0 && borrowIndex == 0, \"market may only be initialized once\");\n\n // Set initial exchange rate\n initialExchangeRateMantissa = initialExchangeRateMantissa_;\n require(initialExchangeRateMantissa > 0, \"initial exchange rate must be greater than zero.\");\n\n // Set the comptroller\n uint err = _setComptroller(comptroller_);\n require(err == uint(Error.NO_ERROR), \"setting comptroller failed\");\n\n // Initialize block number and borrow index (block number mocks depend on comptroller being set)\n accrualBlockNumber = block.number;\n borrowIndex = mantissaOne;\n\n // Set the interest rate model (depends on block number / borrow index)\n err = _setInterestRateModelFresh(interestRateModel_);\n require(err == uint(Error.NO_ERROR), \"setting interest rate model failed\");\n\n name = name_;\n symbol = symbol_;\n decimals = decimals_;\n\n // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\n _notEntered = true;\n }\n\n /**\n * @notice Accrue interest then return the up-to-date exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateCurrent() public nonReentrant returns (uint) {\n require(accrueInterest() == uint(Error.NO_ERROR), \"accrue interest failed\");\n return exchangeRateStored();\n }\n\n /**\n * @notice Applies accrued interest to total borrows and reserves\n * @dev This calculates interest accrued from the last checkpointed block\n * up to the current block and writes new checkpoint to storage and\n * reduce spread reserves to protocol share reserve\n * if currentBlock - reduceReservesBlockNumber >= blockDelta\n */\n // @custom:event Emits AccrueInterest event\n function accrueInterest() public returns (uint) {\n /* Remember the initial block number */\n uint currentBlockNumber = block.number;\n uint accrualBlockNumberPrior = accrualBlockNumber;\n\n /* Short-circuit accumulating 0 interest */\n if (accrualBlockNumberPrior == currentBlockNumber) {\n return uint(Error.NO_ERROR);\n }\n\n /* Read the previous values out of storage */\n uint cashPrior = getCashPrior();\n uint borrowsPrior = totalBorrows;\n uint reservesPrior = totalReserves;\n uint borrowIndexPrior = borrowIndex;\n\n /* Calculate the current borrow interest rate */\n uint borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior);\n require(borrowRateMantissa <= borrowRateMaxMantissa, \"borrow rate is absurdly high\");\n\n /* Calculate the number of blocks elapsed since the last accrual */\n (MathError mathErr, uint blockDelta) = subUInt(currentBlockNumber, accrualBlockNumberPrior);\n ensureNoMathError(mathErr);\n\n /*\n * Calculate the interest accumulated into borrows and reserves and the new index:\n * simpleInterestFactor = borrowRate * blockDelta\n * interestAccumulated = simpleInterestFactor * totalBorrows\n * totalBorrowsNew = interestAccumulated + totalBorrows\n * totalReservesNew = interestAccumulated * reserveFactor + totalReserves\n * borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\n */\n\n Exp memory simpleInterestFactor;\n uint interestAccumulated;\n uint totalBorrowsNew;\n uint totalReservesNew;\n uint borrowIndexNew;\n\n (mathErr, simpleInterestFactor) = mulScalar(Exp({ mantissa: borrowRateMantissa }), blockDelta);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, interestAccumulated) = mulScalarTruncate(simpleInterestFactor, borrowsPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, totalBorrowsNew) = addUInt(interestAccumulated, borrowsPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, totalReservesNew) = mulScalarTruncateAddUInt(\n Exp({ mantissa: reserveFactorMantissa }),\n interestAccumulated,\n reservesPrior\n );\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n (mathErr, borrowIndexNew) = mulScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\n if (mathErr != MathError.NO_ERROR) {\n return\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\n uint(mathErr)\n );\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the previously calculated values into storage */\n accrualBlockNumber = currentBlockNumber;\n borrowIndex = borrowIndexNew;\n totalBorrows = totalBorrowsNew;\n totalReserves = totalReservesNew;\n\n (mathErr, blockDelta) = subUInt(currentBlockNumber, reduceReservesBlockNumber);\n ensureNoMathError(mathErr);\n if (blockDelta >= reduceReservesBlockDelta) {\n reduceReservesBlockNumber = currentBlockNumber;\n if (cashPrior < totalReservesNew) {\n _reduceReservesFresh(cashPrior);\n } else {\n _reduceReservesFresh(totalReservesNew);\n }\n }\n\n /* We emit an AccrueInterest event */\n emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets a new comptroller for the market\n * @dev Admin function to set a new comptroller\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // @custom:event Emits NewComptroller event\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint) {\n // Check caller is admin\n ensureAdmin(msg.sender);\n\n ComptrollerInterface oldComptroller = comptroller;\n // Ensure invoke comptroller.isComptroller() returns true\n require(newComptroller.isComptroller(), \"marker method returned false\");\n\n // Set market's comptroller to newComptroller\n comptroller = newComptroller;\n\n // Emit NewComptroller(oldComptroller, newComptroller)\n emit NewComptroller(oldComptroller, newComptroller);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accrues interest and updates the interest rate model using _setInterestRateModelFresh\n * @dev Governance function to accrue interest and update the interest rate model\n * @param newInterestRateModel_ The new interest rate model to use\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setInterestRateModel(InterestRateModel newInterestRateModel_) public returns (uint) {\n ensureAllowed(\"_setInterestRateModel(address)\");\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted change of interest rate model failed\n return fail(Error(error), FailureInfo.SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED);\n }\n // _setInterestRateModelFresh emits interest-rate-model-update-specific logs on errors, so we don't need to.\n return _setInterestRateModelFresh(newInterestRateModel_);\n }\n\n /**\n * @notice Calculates the exchange rate from the underlying to the VToken\n * @dev This function does not accrue interest before calculating the exchange rate\n * @return Calculated exchange rate scaled by 1e18\n */\n function exchangeRateStored() public view returns (uint) {\n (MathError err, uint result) = exchangeRateStoredInternal();\n ensureNoMathError(err);\n return result;\n }\n\n /**\n * @notice Return the borrow balance of account based on stored data\n * @param account The address whose balance should be calculated\n * @return The calculated balance\n */\n function borrowBalanceStored(address account) public view returns (uint) {\n (MathError err, uint result) = borrowBalanceStoredInternal(account);\n ensureNoMathError(err);\n return result;\n }\n\n /**\n * @notice Transfers `tokens` tokens from `src` to `dst` by `spender`\n * @dev Called by both `transfer` and `transferFrom` internally\n * @param spender The address of the account performing the transfer\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param tokens The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferTokens(address spender, address src, address dst, uint tokens) internal returns (uint) {\n /* Fail if transfer not allowed */\n uint allowed = comptroller.transferAllowed(address(this), src, dst, tokens);\n if (allowed != 0) {\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.TRANSFER_COMPTROLLER_REJECTION, allowed);\n }\n\n /* Do not allow self-transfers */\n if (src == dst) {\n return fail(Error.BAD_INPUT, FailureInfo.TRANSFER_NOT_ALLOWED);\n }\n\n /* Get the allowance, infinite for the account owner */\n uint startingAllowance = 0;\n if (spender == src) {\n startingAllowance = uint(-1);\n } else {\n startingAllowance = transferAllowances[src][spender];\n }\n\n /* Do the calculations, checking for {under,over}flow */\n MathError mathErr;\n uint allowanceNew;\n uint srvTokensNew;\n uint dstTokensNew;\n\n (mathErr, allowanceNew) = subUInt(startingAllowance, tokens);\n if (mathErr != MathError.NO_ERROR) {\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ALLOWED);\n }\n\n (mathErr, srvTokensNew) = subUInt(accountTokens[src], tokens);\n if (mathErr != MathError.NO_ERROR) {\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_NOT_ENOUGH);\n }\n\n (mathErr, dstTokensNew) = addUInt(accountTokens[dst], tokens);\n if (mathErr != MathError.NO_ERROR) {\n return fail(Error.MATH_ERROR, FailureInfo.TRANSFER_TOO_MUCH);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n accountTokens[src] = srvTokensNew;\n accountTokens[dst] = dstTokensNew;\n\n /* Eat some of the allowance (if necessary) */\n if (startingAllowance != uint(-1)) {\n transferAllowances[src][spender] = allowanceNew;\n }\n\n /* We emit a Transfer event */\n emit Transfer(src, dst, tokens);\n\n comptroller.transferVerify(address(this), src, dst, tokens);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Sender supplies assets into the market and receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param mintAmount The amount of the underlying asset to supply\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\n */\n function mintInternal(uint mintAmount) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mint failed\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\n }\n // mintFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n return mintFresh(msg.sender, mintAmount);\n }\n\n /**\n * @notice User supplies assets into the market and receives vTokens in exchange\n * @dev Assumes interest has already been accrued up to the current block\n * @param minter The address of the account which is supplying the assets\n * @param mintAmount The amount of the underlying asset to supply\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\n */\n function mintFresh(address minter, uint mintAmount) internal returns (uint, uint) {\n /* Fail if mint not allowed */\n uint allowed = comptroller.mintAllowed(address(this), minter, mintAmount);\n if (allowed != 0) {\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\n }\n\n MintLocalVars memory vars;\n\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\n if (vars.mathErr != MathError.NO_ERROR) {\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We call `doTransferIn` for the minter and the mintAmount.\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\n * side-effects occurred. The function returns the amount actually transferred,\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\n * of cash.\n */\n vars.actualMintAmount = doTransferIn(minter, mintAmount);\n\n /*\n * We get the current exchange rate and calculate the number of vTokens to be minted:\n * mintTokens = actualMintAmount / exchangeRate\n */\n\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\n vars.actualMintAmount,\n Exp({ mantissa: vars.exchangeRateMantissa })\n );\n ensureNoMathError(vars.mathErr);\n\n /*\n * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\n * totalSupplyNew = totalSupply + mintTokens\n * accountTokensNew = accountTokens[minter] + mintTokens\n */\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\n ensureNoMathError(vars.mathErr);\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[minter], vars.mintTokens);\n ensureNoMathError(vars.mathErr);\n\n /* We write previously calculated values into storage */\n totalSupply = vars.totalSupplyNew;\n accountTokens[minter] = vars.accountTokensNew;\n\n /* We emit a Mint event, and a Transfer event */\n emit Mint(minter, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\n emit Transfer(address(this), minter, vars.mintTokens);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.mintVerify(address(this), minter, vars.actualMintAmount, vars.mintTokens);\n\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\n }\n\n /**\n * @notice Sender supplies assets into the market and receiver receives vTokens in exchange\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param receiver The address of the account which is receiving the vTokens\n * @param mintAmount The amount of the underlying asset to supply\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\n */\n function mintBehalfInternal(address receiver, uint mintAmount) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted mintBehalf failed\n return (fail(Error(error), FailureInfo.MINT_ACCRUE_INTEREST_FAILED), 0);\n }\n // mintBelahfFresh emits the actual Mint event if successful and logs on errors, so we don't need to\n return mintBehalfFresh(msg.sender, receiver, mintAmount);\n }\n\n /**\n * @notice Payer supplies assets into the market and receiver receives vTokens in exchange\n * @dev Assumes interest has already been accrued up to the current block\n * @param payer The address of the account which is paying the underlying token\n * @param receiver The address of the account which is receiving vToken\n * @param mintAmount The amount of the underlying asset to supply\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual mint amount.\n */\n function mintBehalfFresh(address payer, address receiver, uint mintAmount) internal returns (uint, uint) {\n ensureNonZeroAddress(receiver);\n /* Fail if mint not allowed */\n uint allowed = comptroller.mintAllowed(address(this), receiver, mintAmount);\n if (allowed != 0) {\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.MINT_COMPTROLLER_REJECTION, allowed), 0);\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.MINT_FRESHNESS_CHECK), 0);\n }\n\n MintLocalVars memory vars;\n\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\n if (vars.mathErr != MathError.NO_ERROR) {\n return (failOpaque(Error.MATH_ERROR, FailureInfo.MINT_EXCHANGE_RATE_READ_FAILED, uint(vars.mathErr)), 0);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We call `doTransferIn` for the payer and the mintAmount.\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * `doTransferIn` reverts if anything goes wrong, since we can't be sure if\n * side-effects occurred. The function returns the amount actually transferred,\n * in case of a fee. On success, the vToken holds an additional `actualMintAmount`\n * of cash.\n */\n vars.actualMintAmount = doTransferIn(payer, mintAmount);\n\n /*\n * We get the current exchange rate and calculate the number of vTokens to be minted:\n * mintTokens = actualMintAmount / exchangeRate\n */\n\n (vars.mathErr, vars.mintTokens) = divScalarByExpTruncate(\n vars.actualMintAmount,\n Exp({ mantissa: vars.exchangeRateMantissa })\n );\n ensureNoMathError(vars.mathErr);\n\n /*\n * We calculate the new total supply of vTokens and receiver token balance, checking for overflow:\n * totalSupplyNew = totalSupply + mintTokens\n * accountTokensNew = accountTokens[receiver] + mintTokens\n */\n (vars.mathErr, vars.totalSupplyNew) = addUInt(totalSupply, vars.mintTokens);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.accountTokensNew) = addUInt(accountTokens[receiver], vars.mintTokens);\n ensureNoMathError(vars.mathErr);\n\n /* We write previously calculated values into storage */\n totalSupply = vars.totalSupplyNew;\n accountTokens[receiver] = vars.accountTokensNew;\n\n /* We emit a MintBehalf event, and a Transfer event */\n emit MintBehalf(payer, receiver, vars.actualMintAmount, vars.mintTokens, vars.accountTokensNew);\n emit Transfer(address(this), receiver, vars.mintTokens);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.mintVerify(address(this), receiver, vars.actualMintAmount, vars.mintTokens);\n\n return (uint(Error.NO_ERROR), vars.actualMintAmount);\n }\n\n /**\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemer The address of the account which is redeeming the tokens\n * @param receiver The receiver of the tokens\n * @param redeemTokens The number of vTokens to redeem into underlying\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function redeemInternal(\n address redeemer,\n address payable receiver,\n uint redeemTokens\n ) internal nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\n }\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\n return redeemFresh(redeemer, receiver, redeemTokens, 0);\n }\n\n /**\n * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\n * for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\n * @dev Accrues interest whether or not the operation succeeds, unless reverted\n * @param redeemer The address of the account which is redeeming the tokens\n * @param receiver The receiver of the tokens, if called by a delegate\n * @param redeemAmount The amount of underlying to receive from redeeming vTokens\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function redeemUnderlyingInternal(\n address redeemer,\n address payable receiver,\n uint redeemAmount\n ) internal nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted redeem failed\n return fail(Error(error), FailureInfo.REDEEM_ACCRUE_INTEREST_FAILED);\n }\n // redeemFresh emits redeem-specific logs on errors, so we don't need to\n return redeemFresh(redeemer, receiver, 0, redeemAmount);\n }\n\n /**\n * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\n * address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see MarketFacet.updateDelegate)\n * @dev Assumes interest has already been accrued up to the current block\n * @param redeemer The address of the account which is redeeming the tokens\n * @param receiver The receiver of the tokens\n * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\n * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n // solhint-disable-next-line code-complexity\n function redeemFresh(\n address redeemer,\n address payable receiver,\n uint redeemTokensIn,\n uint redeemAmountIn\n ) internal returns (uint) {\n require(redeemTokensIn == 0 || redeemAmountIn == 0, \"one of redeemTokensIn or redeemAmountIn must be zero\");\n\n RedeemLocalVars memory vars;\n\n /* exchangeRate = invoke Exchange Rate Stored() */\n (vars.mathErr, vars.exchangeRateMantissa) = exchangeRateStoredInternal();\n ensureNoMathError(vars.mathErr);\n\n /* If redeemTokensIn > 0: */\n if (redeemTokensIn > 0) {\n /*\n * We calculate the exchange rate and the amount of underlying to be redeemed:\n * redeemTokens = redeemTokensIn\n * redeemAmount = redeemTokensIn x exchangeRateCurrent\n */\n vars.redeemTokens = redeemTokensIn;\n\n (vars.mathErr, vars.redeemAmount) = mulScalarTruncate(\n Exp({ mantissa: vars.exchangeRateMantissa }),\n redeemTokensIn\n );\n ensureNoMathError(vars.mathErr);\n } else {\n /*\n * We get the current exchange rate and calculate the amount to be redeemed:\n * redeemTokens = redeemAmountIn / exchangeRate\n * redeemAmount = redeemAmountIn\n */\n\n (vars.mathErr, vars.redeemTokens) = divScalarByExpTruncate(\n redeemAmountIn,\n Exp({ mantissa: vars.exchangeRateMantissa })\n );\n ensureNoMathError(vars.mathErr);\n\n vars.redeemAmount = redeemAmountIn;\n }\n\n /* Fail if redeem not allowed */\n uint allowed = comptroller.redeemAllowed(address(this), redeemer, vars.redeemTokens);\n if (allowed != 0) {\n revert(\"math error\");\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n revert(\"math error\");\n }\n\n /*\n * We calculate the new total supply and redeemer balance, checking for underflow:\n * totalSupplyNew = totalSupply - redeemTokens\n * accountTokensNew = accountTokens[redeemer] - redeemTokens\n */\n (vars.mathErr, vars.totalSupplyNew) = subUInt(totalSupply, vars.redeemTokens);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.accountTokensNew) = subUInt(accountTokens[redeemer], vars.redeemTokens);\n ensureNoMathError(vars.mathErr);\n\n /* Fail gracefully if protocol has insufficient cash */\n if (getCashPrior() < vars.redeemAmount) {\n revert(\"math error\");\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write previously calculated values into storage */\n totalSupply = vars.totalSupplyNew;\n accountTokens[redeemer] = vars.accountTokensNew;\n\n /*\n * We invoke doTransferOut for the receiver and the redeemAmount.\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * On success, the vToken has redeemAmount less of cash.\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\n */\n\n uint feeAmount;\n uint remainedAmount;\n if (IComptroller(address(comptroller)).treasuryPercent() != 0) {\n (vars.mathErr, feeAmount) = mulUInt(\n vars.redeemAmount,\n IComptroller(address(comptroller)).treasuryPercent()\n );\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, feeAmount) = divUInt(feeAmount, 1e18);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, remainedAmount) = subUInt(vars.redeemAmount, feeAmount);\n ensureNoMathError(vars.mathErr);\n\n doTransferOut(address(uint160(IComptroller(address(comptroller)).treasuryAddress())), feeAmount);\n\n emit RedeemFee(redeemer, feeAmount, vars.redeemTokens);\n } else {\n remainedAmount = vars.redeemAmount;\n }\n\n doTransferOut(receiver, remainedAmount);\n\n /* We emit a Transfer event, and a Redeem event */\n emit Transfer(redeemer, address(this), vars.redeemTokens);\n emit Redeem(redeemer, remainedAmount, vars.redeemTokens, vars.accountTokensNew);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.redeemVerify(address(this), redeemer, vars.redeemAmount, vars.redeemTokens);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Receiver gets the borrow on behalf of the borrower address\n * @param borrower The borrower, on behalf of whom to borrow\n * @param receiver The account that would receive the funds (can be the same as the borrower)\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function borrowInternal(\n address borrower,\n address payable receiver,\n uint borrowAmount\n ) internal nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\n return fail(Error(error), FailureInfo.BORROW_ACCRUE_INTEREST_FAILED);\n }\n // borrowFresh emits borrow-specific logs on errors, so we don't need to\n return borrowFresh(borrower, receiver, borrowAmount);\n }\n\n /**\n * @notice Receiver gets the borrow on behalf of the borrower address\n * @dev Before calling this function, ensure that the interest has been accrued\n * @param borrower The borrower, on behalf of whom to borrow\n * @param receiver The account that would receive the funds (can be the same as the borrower)\n * @param borrowAmount The amount of the underlying asset to borrow\n * @return uint Returns 0 on success, otherwise revert (see ErrorReporter.sol for details).\n */\n function borrowFresh(address borrower, address payable receiver, uint borrowAmount) internal returns (uint) {\n /* Revert if borrow not allowed */\n uint allowed = comptroller.borrowAllowed(address(this), borrower, borrowAmount);\n if (allowed != 0) {\n revert(\"math error\");\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n revert(\"math error\");\n }\n\n /* Revert if protocol has insufficient underlying cash */\n if (getCashPrior() < borrowAmount) {\n revert(\"math error\");\n }\n\n BorrowLocalVars memory vars;\n\n /*\n * We calculate the new borrower and total borrow balances, failing on overflow:\n * accountBorrowsNew = accountBorrows + borrowAmount\n * totalBorrowsNew = totalBorrows + borrowAmount\n */\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.accountBorrowsNew) = addUInt(vars.accountBorrows, borrowAmount);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.totalBorrowsNew) = addUInt(totalBorrows, borrowAmount);\n ensureNoMathError(vars.mathErr);\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the previously calculated values into storage */\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = vars.totalBorrowsNew;\n\n /*\n * We invoke doTransferOut for the receiver and the borrowAmount.\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * On success, the vToken borrowAmount less of cash.\n * doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\n */\n doTransferOut(receiver, borrowAmount);\n\n /* We emit a Borrow event */\n emit Borrow(borrower, borrowAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.borrowVerify(address(this), borrower, borrowAmount);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Sender repays their own borrow\n * @param repayAmount The amount to repay\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n function repayBorrowInternal(uint repayAmount) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\n return (fail(Error(error), FailureInfo.REPAY_BORROW_ACCRUE_INTEREST_FAILED), 0);\n }\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n return repayBorrowFresh(msg.sender, msg.sender, repayAmount);\n }\n\n /**\n * @notice Sender repays a borrow belonging to another borrowing account\n * @param borrower The account with the debt being payed off\n * @param repayAmount The amount to repay\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n function repayBorrowBehalfInternal(address borrower, uint repayAmount) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted borrow failed\n return (fail(Error(error), FailureInfo.REPAY_BEHALF_ACCRUE_INTEREST_FAILED), 0);\n }\n // repayBorrowFresh emits repay-borrow-specific logs on errors, so we don't need to\n return repayBorrowFresh(msg.sender, borrower, repayAmount);\n }\n\n /**\n * @notice Borrows are repaid by another user (possibly the borrower).\n * @param payer The account paying off the borrow\n * @param borrower The account with the debt being payed off\n * @param repayAmount The amount of undelrying tokens being returned\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n function repayBorrowFresh(address payer, address borrower, uint repayAmount) internal returns (uint, uint) {\n /* Fail if repayBorrow not allowed */\n uint allowed = comptroller.repayBorrowAllowed(address(this), payer, borrower, repayAmount);\n if (allowed != 0) {\n return (\n failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.REPAY_BORROW_COMPTROLLER_REJECTION, allowed),\n 0\n );\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.REPAY_BORROW_FRESHNESS_CHECK), 0);\n }\n\n RepayBorrowLocalVars memory vars;\n\n /* We remember the original borrowerIndex for verification purposes */\n vars.borrowerIndex = accountBorrows[borrower].interestIndex;\n\n /* We fetch the amount the borrower owes, with accumulated interest */\n (vars.mathErr, vars.accountBorrows) = borrowBalanceStoredInternal(borrower);\n if (vars.mathErr != MathError.NO_ERROR) {\n return (\n failOpaque(\n Error.MATH_ERROR,\n FailureInfo.REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\n uint(vars.mathErr)\n ),\n 0\n );\n }\n\n /* If repayAmount == -1, repayAmount = accountBorrows */\n if (repayAmount == uint(-1)) {\n vars.repayAmount = vars.accountBorrows;\n } else {\n vars.repayAmount = repayAmount;\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We call doTransferIn for the payer and the repayAmount\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * On success, the vToken holds an additional repayAmount of cash.\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\n * it returns the amount actually transferred, in case of a fee.\n */\n vars.actualRepayAmount = doTransferIn(payer, vars.repayAmount);\n\n /*\n * We calculate the new borrower and total borrow balances, failing on underflow:\n * accountBorrowsNew = accountBorrows - actualRepayAmount\n * totalBorrowsNew = totalBorrows - actualRepayAmount\n */\n (vars.mathErr, vars.accountBorrowsNew) = subUInt(vars.accountBorrows, vars.actualRepayAmount);\n ensureNoMathError(vars.mathErr);\n\n (vars.mathErr, vars.totalBorrowsNew) = subUInt(totalBorrows, vars.actualRepayAmount);\n ensureNoMathError(vars.mathErr);\n\n /* We write the previously calculated values into storage */\n accountBorrows[borrower].principal = vars.accountBorrowsNew;\n accountBorrows[borrower].interestIndex = borrowIndex;\n totalBorrows = vars.totalBorrowsNew;\n\n /* We emit a RepayBorrow event */\n emit RepayBorrow(payer, borrower, vars.actualRepayAmount, vars.accountBorrowsNew, vars.totalBorrowsNew);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.repayBorrowVerify(address(this), payer, borrower, vars.actualRepayAmount, vars.borrowerIndex);\n\n return (uint(Error.NO_ERROR), vars.actualRepayAmount);\n }\n\n /**\n * @notice The sender liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n function liquidateBorrowInternal(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) internal nonReentrant returns (uint, uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED), 0);\n }\n\n error = vTokenCollateral.accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\n return (fail(Error(error), FailureInfo.LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED), 0);\n }\n\n // liquidateBorrowFresh emits borrow-specific logs on errors, so we don't need to\n return liquidateBorrowFresh(msg.sender, borrower, repayAmount, vTokenCollateral);\n }\n\n /**\n * @notice The liquidator liquidates the borrowers collateral.\n * The collateral seized is transferred to the liquidator.\n * @param borrower The borrower of this vToken to be liquidated\n * @param liquidator The address repaying the borrow and seizing collateral\n * @param vTokenCollateral The market in which to seize collateral from the borrower\n * @param repayAmount The amount of the underlying borrowed asset to repay\n * @return (uint, uint) An error code (0=success, otherwise a failure, see ErrorReporter.sol), and the actual repayment amount.\n */\n // solhint-disable-next-line code-complexity\n function liquidateBorrowFresh(\n address liquidator,\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) internal returns (uint, uint) {\n /* Fail if liquidate not allowed */\n uint allowed = comptroller.liquidateBorrowAllowed(\n address(this),\n address(vTokenCollateral),\n liquidator,\n borrower,\n repayAmount\n );\n if (allowed != 0) {\n return (failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_COMPTROLLER_REJECTION, allowed), 0);\n }\n\n /* Verify market's block number equals current block number */\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_FRESHNESS_CHECK), 0);\n }\n\n /* Verify vTokenCollateral market's block number equals current block number */\n if (vTokenCollateral.accrualBlockNumber() != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.LIQUIDATE_COLLATERAL_FRESHNESS_CHECK), 0);\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n return (fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_LIQUIDATOR_IS_BORROWER), 0);\n }\n\n /* Fail if repayAmount = 0 */\n if (repayAmount == 0) {\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_ZERO), 0);\n }\n\n /* Fail if repayAmount = -1 */\n if (repayAmount == uint(-1)) {\n return (fail(Error.INVALID_CLOSE_AMOUNT_REQUESTED, FailureInfo.LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX), 0);\n }\n\n /* Fail if repayBorrow fails */\n (uint repayBorrowError, uint actualRepayAmount) = repayBorrowFresh(liquidator, borrower, repayAmount);\n if (repayBorrowError != uint(Error.NO_ERROR)) {\n return (fail(Error(repayBorrowError), FailureInfo.LIQUIDATE_REPAY_BORROW_FRESH_FAILED), 0);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We calculate the number of collateral tokens that will be seized */\n (uint amountSeizeError, uint seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\n address(this),\n address(vTokenCollateral),\n actualRepayAmount\n );\n require(amountSeizeError == uint(Error.NO_ERROR), \"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\");\n\n /* Revert if borrower collateral token balance < seizeTokens */\n require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \"LIQUIDATE_SEIZE_TOO_MUCH\");\n\n // If this is also the collateral, run seizeInternal to avoid re-entrancy, otherwise make an external call\n uint seizeError;\n if (address(vTokenCollateral) == address(this)) {\n seizeError = seizeInternal(address(this), liquidator, borrower, seizeTokens);\n } else {\n seizeError = vTokenCollateral.seize(liquidator, borrower, seizeTokens);\n }\n\n /* Revert if seize tokens fails (since we cannot be sure of side effects) */\n require(seizeError == uint(Error.NO_ERROR), \"token seizure failed\");\n\n /* We emit a LiquidateBorrow event */\n emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.liquidateBorrowVerify(\n address(this),\n address(vTokenCollateral),\n liquidator,\n borrower,\n actualRepayAmount,\n seizeTokens\n );\n\n return (uint(Error.NO_ERROR), actualRepayAmount);\n }\n\n /**\n * @notice Transfers collateral tokens (this market) to the liquidator.\n * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another vToken.\n * Its absolutely critical to use msg.sender as the seizer vToken and not a parameter.\n * @param seizerToken The contract seizing the collateral (i.e. borrowed vToken)\n * @param liquidator The account receiving seized collateral\n * @param borrower The account having collateral seized\n * @param seizeTokens The number of vTokens to seize\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function seizeInternal(\n address seizerToken,\n address liquidator,\n address borrower,\n uint seizeTokens\n ) internal returns (uint) {\n /* Fail if seize not allowed */\n uint allowed = comptroller.seizeAllowed(address(this), seizerToken, liquidator, borrower, seizeTokens);\n if (allowed != 0) {\n return failOpaque(Error.COMPTROLLER_REJECTION, FailureInfo.LIQUIDATE_SEIZE_COMPTROLLER_REJECTION, allowed);\n }\n\n /* Fail if borrower = liquidator */\n if (borrower == liquidator) {\n return fail(Error.INVALID_ACCOUNT_PAIR, FailureInfo.LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER);\n }\n\n MathError mathErr;\n uint borrowerTokensNew;\n uint liquidatorTokensNew;\n\n /*\n * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\n * borrowerTokensNew = accountTokens[borrower] - seizeTokens\n * liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\n */\n (mathErr, borrowerTokensNew) = subUInt(accountTokens[borrower], seizeTokens);\n if (mathErr != MathError.NO_ERROR) {\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED, uint(mathErr));\n }\n\n (mathErr, liquidatorTokensNew) = addUInt(accountTokens[liquidator], seizeTokens);\n if (mathErr != MathError.NO_ERROR) {\n return failOpaque(Error.MATH_ERROR, FailureInfo.LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED, uint(mathErr));\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /* We write the previously calculated values into storage */\n accountTokens[borrower] = borrowerTokensNew;\n accountTokens[liquidator] = liquidatorTokensNew;\n\n /* Emit a Transfer event */\n emit Transfer(borrower, liquidator, seizeTokens);\n\n /* We call the defense and prime accrue interest hook */\n comptroller.seizeVerify(address(this), seizerToken, liquidator, borrower, seizeTokens);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Sets a new reserve factor for the protocol (requires fresh interest accrual)\n * @dev Governance function to set a new reserve factor\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setReserveFactorFresh(uint newReserveFactorMantissa) internal returns (uint) {\n // Verify market's block number equals current block number\n if (accrualBlockNumber != block.number) {\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_RESERVE_FACTOR_FRESH_CHECK);\n }\n\n // Check newReserveFactor ≤ maxReserveFactor\n if (newReserveFactorMantissa > reserveFactorMaxMantissa) {\n return fail(Error.BAD_INPUT, FailureInfo.SET_RESERVE_FACTOR_BOUNDS_CHECK);\n }\n\n uint oldReserveFactorMantissa = reserveFactorMantissa;\n reserveFactorMantissa = newReserveFactorMantissa;\n\n emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accrues interest and adds reserves by transferring from `msg.sender`\n * @param addAmount Amount of addition to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _addReservesInternal(uint addAmount) internal nonReentrant returns (uint) {\n uint error = accrueInterest();\n if (error != uint(Error.NO_ERROR)) {\n // accrueInterest emits logs on errors, but on top of that we want to log the fact that an attempted reduce reserves failed.\n return fail(Error(error), FailureInfo.ADD_RESERVES_ACCRUE_INTEREST_FAILED);\n }\n\n // _addReservesFresh emits reserve-addition-specific logs on errors, so we don't need to.\n (error, ) = _addReservesFresh(addAmount);\n return error;\n }\n\n /**\n * @notice Add reserves by transferring from caller\n * @dev Requires fresh interest accrual\n * @param addAmount Amount of addition to reserves\n * @return (uint, uint) An error code (0=success, otherwise a failure (see ErrorReporter.sol for details)) and the actual amount added, net token fees\n */\n function _addReservesFresh(uint addAmount) internal returns (uint, uint) {\n // totalReserves + actualAddAmount\n uint totalReservesNew;\n uint actualAddAmount;\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != block.number) {\n return (fail(Error.MARKET_NOT_FRESH, FailureInfo.ADD_RESERVES_FRESH_CHECK), actualAddAmount);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n /*\n * We call doTransferIn for the caller and the addAmount\n * Note: The vToken must handle variations between BEP-20 and BNB underlying.\n * On success, the vToken holds an additional addAmount of cash.\n * doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\n * it returns the amount actually transferred, in case of a fee.\n */\n\n actualAddAmount = doTransferIn(msg.sender, addAmount);\n\n totalReservesNew = totalReserves + actualAddAmount;\n\n /* Revert on overflow */\n require(totalReservesNew >= totalReserves, \"add reserves unexpected overflow\");\n\n // Store reserves[n+1] = reserves[n] + actualAddAmount\n totalReserves = totalReservesNew;\n\n /* Emit NewReserves(admin, actualAddAmount, reserves[n+1]) */\n emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\n\n /* Return (NO_ERROR, actualAddAmount) */\n return (uint(Error.NO_ERROR), actualAddAmount);\n }\n\n /**\n * @notice Reduces reserves by transferring to protocol share reserve contract\n * @dev Requires fresh interest accrual\n * @param reduceAmount Amount of reduction to reserves\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _reduceReservesFresh(uint reduceAmount) internal returns (uint) {\n if (reduceAmount == 0) {\n return uint(Error.NO_ERROR);\n }\n\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != block.number) {\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.REDUCE_RESERVES_FRESH_CHECK);\n }\n\n // Fail gracefully if protocol has insufficient underlying cash\n if (getCashPrior() < reduceAmount) {\n return fail(Error.TOKEN_INSUFFICIENT_CASH, FailureInfo.REDUCE_RESERVES_CASH_NOT_AVAILABLE);\n }\n\n // Check reduceAmount ≤ reserves[n] (totalReserves)\n if (reduceAmount > totalReserves) {\n return fail(Error.BAD_INPUT, FailureInfo.REDUCE_RESERVES_VALIDATION);\n }\n\n /////////////////////////\n // EFFECTS & INTERACTIONS\n // (No safe failures beyond this point)\n\n // totalReserves - reduceAmount\n uint totalReservesNew = totalReserves - reduceAmount;\n\n // Store reserves[n+1] = reserves[n] - reduceAmount\n totalReserves = totalReservesNew;\n\n // doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\n doTransferOut(protocolShareReserve, reduceAmount);\n\n IProtocolShareReserveV5(protocolShareReserve).updateAssetsState(\n address(comptroller),\n underlying,\n IProtocolShareReserveV5.IncomeType.SPREAD\n );\n\n emit ReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice updates the interest rate model (requires fresh interest accrual)\n * @dev Governance function to update the interest rate model\n * @param newInterestRateModel the new interest rate model to use\n * @return uint Returns 0 on success, otherwise returns a failure code (see ErrorReporter.sol for details).\n */\n function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal returns (uint) {\n // Used to store old model for use in the event that is emitted on success\n InterestRateModel oldInterestRateModel;\n // We fail gracefully unless market's block number equals current block number\n if (accrualBlockNumber != block.number) {\n return fail(Error.MARKET_NOT_FRESH, FailureInfo.SET_INTEREST_RATE_MODEL_FRESH_CHECK);\n }\n\n // Track the market's current interest rate model\n oldInterestRateModel = interestRateModel;\n\n // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\n require(newInterestRateModel.isInterestRateModel(), \"marker method returned false\");\n\n // Set the interest rate model to newInterestRateModel\n interestRateModel = newInterestRateModel;\n\n // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\n emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\n\n return uint(Error.NO_ERROR);\n }\n\n /*** Safe Token ***/\n\n /**\n * @dev Performs a transfer in, reverting upon failure. Returns the amount actually transferred to the protocol, in case of a fee.\n * This may revert due to insufficient balance or insufficient allowance.\n */\n function doTransferIn(address from, uint amount) internal returns (uint);\n\n /**\n * @dev Performs a transfer out, ideally returning an explanatory error code upon failure rather than reverting.\n * If caller has not called checked protocol's balance, may revert due to insufficient cash held in the contract.\n * If caller has checked protocol's balance, and verified it is >= amount, this should not revert in normal conditions.\n */\n function doTransferOut(address payable to, uint amount) internal;\n\n /**\n * @notice Return the borrow balance of account based on stored data\n * @param account The address whose balance should be calculated\n * @return Tuple of error code and the calculated balance or 0 if error code is non-zero\n */\n function borrowBalanceStoredInternal(address account) internal view returns (MathError, uint) {\n /* Note: we do not assert that the market is up to date */\n MathError mathErr;\n uint principalTimesIndex;\n uint result;\n\n /* Get borrowBalance and borrowIndex */\n BorrowSnapshot storage borrowSnapshot = accountBorrows[account];\n\n /* If borrowBalance = 0 then borrowIndex is likely also 0.\n * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\n */\n if (borrowSnapshot.principal == 0) {\n return (MathError.NO_ERROR, 0);\n }\n\n /* Calculate new borrow balance using the interest index:\n * recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\n */\n (mathErr, principalTimesIndex) = mulUInt(borrowSnapshot.principal, borrowIndex);\n if (mathErr != MathError.NO_ERROR) {\n return (mathErr, 0);\n }\n\n (mathErr, result) = divUInt(principalTimesIndex, borrowSnapshot.interestIndex);\n if (mathErr != MathError.NO_ERROR) {\n return (mathErr, 0);\n }\n\n return (MathError.NO_ERROR, result);\n }\n\n /**\n * @notice Calculates the exchange rate from the underlying to the vToken\n * @dev This function does not accrue interest before calculating the exchange rate\n * @return Tuple of error code and calculated exchange rate scaled by 1e18\n */\n function exchangeRateStoredInternal() internal view returns (MathError, uint) {\n uint _totalSupply = totalSupply;\n if (_totalSupply == 0) {\n /*\n * If there are no tokens minted:\n * exchangeRate = initialExchangeRate\n */\n return (MathError.NO_ERROR, initialExchangeRateMantissa);\n } else {\n /*\n * Otherwise:\n * exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply\n */\n uint totalCash = getCashPrior();\n uint cashPlusBorrowsMinusReserves;\n Exp memory exchangeRate;\n MathError mathErr;\n\n (mathErr, cashPlusBorrowsMinusReserves) = addThenSubUInt(totalCash, totalBorrows, totalReserves);\n if (mathErr != MathError.NO_ERROR) {\n return (mathErr, 0);\n }\n\n (mathErr, exchangeRate) = getExp(cashPlusBorrowsMinusReserves, _totalSupply);\n if (mathErr != MathError.NO_ERROR) {\n return (mathErr, 0);\n }\n\n return (MathError.NO_ERROR, exchangeRate.mantissa);\n }\n }\n\n function ensureAllowed(string memory functionSig) private view {\n require(\n IAccessControlManagerV5(accessControlManager).isAllowedToCall(msg.sender, functionSig),\n \"access denied\"\n );\n }\n\n function ensureAdmin(address caller_) private view {\n require(caller_ == admin, \"Unauthorized\");\n }\n\n function ensureNoMathError(MathError mErr) private pure {\n require(mErr == MathError.NO_ERROR, \"math error\");\n }\n\n function ensureNonZeroAddress(address address_) private pure {\n require(address_ != address(0), \"zero address\");\n }\n\n /*** Safe Token ***/\n\n /**\n * @notice Gets balance of this contract in terms of the underlying\n * @dev This excludes the value of the current message, if any\n * @return The quantity of underlying owned by this contract\n */\n function getCashPrior() internal view returns (uint);\n}\n" + }, + "contracts/Tokens/VTokens/VTokenInterfaces.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Comptroller/ComptrollerInterface.sol\";\nimport \"../../InterestRateModels/InterestRateModel.sol\";\n\ninterface IProtocolShareReserveV5 {\n enum IncomeType {\n SPREAD,\n LIQUIDATION\n }\n\n function updateAssetsState(address comptroller, address asset, IncomeType kind) external;\n}\n\ncontract VTokenStorageBase {\n /**\n * @notice Container for borrow balance information\n * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\n * @member interestIndex Global borrowIndex as of the most recent balance-changing action\n */\n struct BorrowSnapshot {\n uint principal;\n uint interestIndex;\n }\n\n /**\n * @dev Guard variable for re-entrancy checks\n */\n bool internal _notEntered;\n\n /**\n * @notice EIP-20 token name for this token\n */\n string public name;\n\n /**\n * @notice EIP-20 token symbol for this token\n */\n string public symbol;\n\n /**\n * @notice EIP-20 token decimals for this token\n */\n uint8 public decimals;\n\n /**\n * @notice Maximum borrow rate that can ever be applied (.0005% / block)\n */\n\n uint internal constant borrowRateMaxMantissa = 0.0005e16;\n\n /**\n * @notice Maximum fraction of interest that can be set aside for reserves\n */\n uint internal constant reserveFactorMaxMantissa = 1e18;\n\n /**\n * @notice Administrator for this contract\n */\n address payable public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address payable public pendingAdmin;\n\n /**\n * @notice Contract which oversees inter-vToken operations\n */\n ComptrollerInterface public comptroller;\n\n /**\n * @notice Model which tells what the current interest rate should be\n */\n InterestRateModel public interestRateModel;\n\n /**\n * @notice Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\n */\n uint internal initialExchangeRateMantissa;\n\n /**\n * @notice Fraction of interest currently set aside for reserves\n */\n uint public reserveFactorMantissa;\n\n /**\n * @notice Block number that interest was last accrued at\n */\n uint public accrualBlockNumber;\n\n /**\n * @notice Accumulator of the total earned interest rate since the opening of the market\n */\n uint public borrowIndex;\n\n /**\n * @notice Total amount of outstanding borrows of the underlying in this market\n */\n uint public totalBorrows;\n\n /**\n * @notice Total amount of reserves of the underlying held in this market\n */\n uint public totalReserves;\n\n /**\n * @notice Total number of tokens in circulation\n */\n uint public totalSupply;\n\n /**\n * @notice Official record of token balances for each account\n */\n mapping(address => uint) internal accountTokens;\n\n /**\n * @notice Approved token transfer amounts on behalf of others\n */\n mapping(address => mapping(address => uint)) internal transferAllowances;\n\n /**\n * @notice Mapping of account addresses to outstanding borrow balances\n */\n mapping(address => BorrowSnapshot) internal accountBorrows;\n\n /**\n * @notice Underlying asset for this VToken\n */\n address public underlying;\n\n /**\n * @notice Implementation address for this contract\n */\n address public implementation;\n\n /**\n * @notice delta block after which reserves will be reduced\n */\n uint public reduceReservesBlockDelta;\n\n /**\n * @notice last block number at which reserves were reduced\n */\n uint public reduceReservesBlockNumber;\n\n /**\n * @notice address of protocol share reserve contract\n */\n address payable public protocolShareReserve;\n\n /**\n * @notice address of accessControlManager\n */\n\n address public accessControlManager;\n}\n\ncontract VTokenStorage is VTokenStorageBase {\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\ncontract VTokenInterface is VTokenStorage {\n /**\n * @notice Indicator that this is a vToken contract (for inspection)\n */\n bool public constant isVToken = true;\n\n /*** Market Events ***/\n\n /**\n * @notice Event emitted when interest is accrued\n */\n event AccrueInterest(uint cashPrior, uint interestAccumulated, uint borrowIndex, uint totalBorrows);\n\n /**\n * @notice Event emitted when tokens are minted\n */\n event Mint(address minter, uint mintAmount, uint mintTokens, uint256 totalSupply);\n\n /**\n * @notice Event emitted when tokens are minted behalf by payer to receiver\n */\n event MintBehalf(address payer, address receiver, uint mintAmount, uint mintTokens, uint256 totalSupply);\n\n /**\n * @notice Event emitted when tokens are redeemed\n */\n event Redeem(address redeemer, uint redeemAmount, uint redeemTokens, uint256 totalSupply);\n\n /**\n * @notice Event emitted when tokens are redeemed and fee is transferred\n */\n event RedeemFee(address redeemer, uint feeAmount, uint redeemTokens);\n\n /**\n * @notice Event emitted when underlying is borrowed\n */\n event Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows);\n\n /**\n * @notice Event emitted when a borrow is repaid\n */\n event RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows);\n\n /**\n * @notice Event emitted when a borrow is liquidated\n */\n event LiquidateBorrow(\n address liquidator,\n address borrower,\n uint repayAmount,\n address vTokenCollateral,\n uint seizeTokens\n );\n\n /*** Admin Events ***/\n\n /**\n * @notice Event emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Event emitted when pendingAdmin is accepted, which means admin has been updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n /**\n * @notice Event emitted when comptroller is changed\n */\n event NewComptroller(ComptrollerInterface oldComptroller, ComptrollerInterface newComptroller);\n\n /**\n * @notice Event emitted when interestRateModel is changed\n */\n event NewMarketInterestRateModel(InterestRateModel oldInterestRateModel, InterestRateModel newInterestRateModel);\n\n /**\n * @notice Event emitted when the reserve factor is changed\n */\n event NewReserveFactor(uint oldReserveFactorMantissa, uint newReserveFactorMantissa);\n\n /**\n * @notice Event emitted when the reserves are added\n */\n event ReservesAdded(address benefactor, uint addAmount, uint newTotalReserves);\n\n /**\n * @notice Event emitted when the reserves are reduced\n */\n event ReservesReduced(address protocolShareReserve, uint reduceAmount, uint newTotalReserves);\n\n /**\n * @notice EIP20 Transfer event\n */\n event Transfer(address indexed from, address indexed to, uint amount);\n\n /**\n * @notice EIP20 Approval event\n */\n event Approval(address indexed owner, address indexed spender, uint amount);\n\n /**\n * @notice Event emitted when block delta for reduce reserves get updated\n */\n event NewReduceReservesBlockDelta(uint256 oldReduceReservesBlockDelta, uint256 newReduceReservesBlockDelta);\n\n /**\n * @notice Event emitted when address of ProtocolShareReserve contract get updated\n */\n event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\n\n /**\n * @notice Failure event\n */\n event Failure(uint error, uint info, uint detail);\n\n /// @notice Emitted when access control address is changed by admin\n event NewAccessControlManager(address oldAccessControlAddress, address newAccessControlAddress);\n\n /*** User Interface ***/\n\n function transfer(address dst, uint amount) external returns (bool);\n\n function transferFrom(address src, address dst, uint amount) external returns (bool);\n\n function approve(address spender, uint amount) external returns (bool);\n\n function balanceOfUnderlying(address owner) external returns (uint);\n\n function totalBorrowsCurrent() external returns (uint);\n\n function borrowBalanceCurrent(address account) external returns (uint);\n\n function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\n\n /*** Admin Function ***/\n function _setPendingAdmin(address payable newPendingAdmin) external returns (uint);\n\n /*** Admin Function ***/\n function _acceptAdmin() external returns (uint);\n\n /*** Admin Function ***/\n function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);\n\n /*** Admin Function ***/\n function _reduceReserves(uint reduceAmount) external returns (uint);\n\n function balanceOf(address owner) external view returns (uint);\n\n function allowance(address owner, address spender) external view returns (uint);\n\n function getAccountSnapshot(address account) external view returns (uint, uint, uint, uint);\n\n function borrowRatePerBlock() external view returns (uint);\n\n function supplyRatePerBlock() external view returns (uint);\n\n function getCash() external view returns (uint);\n\n function exchangeRateCurrent() public returns (uint);\n\n function accrueInterest() public returns (uint);\n\n /*** Admin Function ***/\n function _setComptroller(ComptrollerInterface newComptroller) public returns (uint);\n\n /*** Admin Function ***/\n function _setInterestRateModel(InterestRateModel newInterestRateModel) public returns (uint);\n\n function borrowBalanceStored(address account) public view returns (uint);\n\n function exchangeRateStored() public view returns (uint);\n}\n\ncontract VBep20Interface {\n /*** User Interface ***/\n\n function mint(uint mintAmount) external returns (uint);\n\n function mintBehalf(address receiver, uint mintAmount) external returns (uint);\n\n function redeem(uint redeemTokens) external returns (uint);\n\n function redeemUnderlying(uint redeemAmount) external returns (uint);\n\n function borrow(uint borrowAmount) external returns (uint);\n\n function repayBorrow(uint repayAmount) external returns (uint);\n\n function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);\n\n function liquidateBorrow(\n address borrower,\n uint repayAmount,\n VTokenInterface vTokenCollateral\n ) external returns (uint);\n\n /*** Admin Functions ***/\n\n function _addReserves(uint addAmount) external returns (uint);\n}\n\ncontract VDelegatorInterface {\n /**\n * @notice Emitted when implementation is changed\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n * @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation\n * @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation\n */\n function _setImplementation(\n address implementation_,\n bool allowResign,\n bytes memory becomeImplementationData\n ) public;\n}\n\ncontract VDelegateInterface {\n /**\n * @notice Called by the delegator on a delegate to initialize it for duty\n * @dev Should revert if any issues arise which make it unfit for delegation\n * @param data The encoded bytes data for any initialization\n */\n function _becomeImplementation(bytes memory data) public;\n\n /**\n * @notice Called by the delegator on a delegate to forfeit its responsibility\n */\n function _resignImplementation() public;\n}\n" + }, + "contracts/Tokens/XVS/IXVSVesting.sol": { + "content": "pragma solidity ^0.5.16;\n\ninterface IXVSVesting {\n /// @param _recipient Address of the Vesting. recipient entitled to claim the vested funds\n /// @param _amount Total number of tokens Vested\n function deposit(address _recipient, uint256 _amount) external;\n}\n" + }, + "contracts/Tokens/XVS/XVS.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/Tokenlock.sol\";\n\ncontract XVS is Tokenlock {\n /// @notice BEP-20 token name for this token\n string public constant name = \"Venus\";\n\n /// @notice BEP-20 token symbol for this token\n string public constant symbol = \"XVS\";\n\n /// @notice BEP-20 token decimals for this token\n uint8 public constant decimals = 18;\n\n /// @notice Total number of tokens in circulation\n uint public constant totalSupply = 30000000e18; // 30 million XVS\n\n /// @notice Allowance amounts on behalf of others\n mapping(address => mapping(address => uint96)) internal allowances;\n\n /// @notice Official record of token balances for each account\n mapping(address => uint96) internal balances;\n\n /// @notice A record of each accounts delegate\n mapping(address => address) public delegates;\n\n /// @notice A checkpoint for marking number of votes from a given block\n struct Checkpoint {\n uint32 fromBlock;\n uint96 votes;\n }\n\n /// @notice A record of votes checkpoints for each account, by index\n mapping(address => mapping(uint32 => Checkpoint)) public checkpoints;\n\n /// @notice The number of checkpoints for each account\n mapping(address => uint32) public numCheckpoints;\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation struct used by the contract\n bytes32 public constant DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n /// @notice A record of states for signing / validating signatures\n mapping(address => uint) public nonces;\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /// @notice An event thats emitted when a delegate account's vote balance changes\n event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);\n\n /// @notice The standard BEP-20 transfer event\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /// @notice The standard BEP-20 approval event\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Construct a new XVS token\n * @param account The initial account to grant all the tokens\n */\n constructor(address account) public {\n balances[account] = uint96(totalSupply);\n emit Transfer(address(0), account, totalSupply);\n }\n\n /**\n * @notice Get the number of tokens `spender` is approved to spend on behalf of `account`\n * @param account The address of the account holding the funds\n * @param spender The address of the account spending the funds\n * @return The number of tokens approved\n */\n function allowance(address account, address spender) external view returns (uint) {\n return allowances[account][spender];\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * @param spender The address of the account which may transfer tokens\n * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint rawAmount) external validLock returns (bool) {\n uint96 amount;\n if (rawAmount == uint(-1)) {\n amount = uint96(-1);\n } else {\n amount = safe96(rawAmount, \"XVS::approve: amount exceeds 96 bits\");\n }\n\n allowances[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @notice Get the number of tokens held by the `account`\n * @param account The address of the account to get the balance of\n * @return The number of tokens held\n */\n function balanceOf(address account) external view returns (uint) {\n return balances[account];\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint rawAmount) external validLock returns (bool) {\n uint96 amount = safe96(rawAmount, \"XVS::transfer: amount exceeds 96 bits\");\n _transferTokens(msg.sender, dst, amount);\n return true;\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint rawAmount) external validLock returns (bool) {\n address spender = msg.sender;\n uint96 spenderAllowance = allowances[src][spender];\n uint96 amount = safe96(rawAmount, \"XVS::approve: amount exceeds 96 bits\");\n\n if (spender != src && spenderAllowance != uint96(-1)) {\n uint96 newAllowance = sub96(\n spenderAllowance,\n amount,\n \"XVS::transferFrom: transfer amount exceeds spender allowance\"\n );\n allowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n }\n\n _transferTokens(src, dst, amount);\n return true;\n }\n\n /**\n * @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The address to delegate votes to\n */\n function delegate(address delegatee) public validLock {\n return _delegate(msg.sender, delegatee);\n }\n\n /**\n * @notice Delegates votes from signatory to `delegatee`\n * @param delegatee The address to delegate votes to\n * @param nonce The contract state required to match the signature\n * @param expiry The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public validLock {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"XVS::delegateBySig: invalid signature\");\n require(nonce == nonces[signatory]++, \"XVS::delegateBySig: invalid nonce\");\n require(now <= expiry, \"XVS::delegateBySig: signature expired\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Gets the current votes balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for `account`\n */\n function getCurrentVotes(address account) external view returns (uint96) {\n uint32 nCheckpoints = numCheckpoints[account];\n return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n /**\n * @notice Determine the prior number of votes for an account as of a block number\n * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.\n * @param account The address of the account to check\n * @param blockNumber The block number to get the vote balance at\n * @return The number of votes the account had as of the given block\n */\n function getPriorVotes(address account, uint blockNumber) public view returns (uint96) {\n require(blockNumber < block.number, \"XVS::getPriorVotes: not yet determined\");\n\n uint32 nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n }\n\n // First check most recent balance\n if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {\n return checkpoints[account][nCheckpoints - 1].votes;\n }\n\n // Next check implicit zero balance\n if (checkpoints[account][0].fromBlock > blockNumber) {\n return 0;\n }\n\n uint32 lower = 0;\n uint32 upper = nCheckpoints - 1;\n while (upper > lower) {\n uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n Checkpoint memory cp = checkpoints[account][center];\n if (cp.fromBlock == blockNumber) {\n return cp.votes;\n } else if (cp.fromBlock < blockNumber) {\n lower = center;\n } else {\n upper = center - 1;\n }\n }\n return checkpoints[account][lower].votes;\n }\n\n function _delegate(address delegator, address delegatee) internal {\n address currentDelegate = delegates[delegator];\n uint96 delegatorBalance = balances[delegator];\n delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _transferTokens(address src, address dst, uint96 amount) internal {\n require(src != address(0), \"XVS::_transferTokens: cannot transfer from the zero address\");\n require(dst != address(0), \"XVS::_transferTokens: cannot transfer to the zero address\");\n\n balances[src] = sub96(balances[src], amount, \"XVS::_transferTokens: transfer amount exceeds balance\");\n balances[dst] = add96(balances[dst], amount, \"XVS::_transferTokens: transfer amount overflows\");\n emit Transfer(src, dst, amount);\n\n _moveDelegates(delegates[src], delegates[dst], amount);\n }\n\n function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {\n if (srcRep != dstRep && amount > 0) {\n if (srcRep != address(0)) {\n uint32 srcRepNum = numCheckpoints[srcRep];\n uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n uint96 srcRepNew = sub96(srcRepOld, amount, \"XVS::_moveVotes: vote amount underflows\");\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint96 dstRepNew = add96(dstRepOld, amount, \"XVS::_moveVotes: vote amount overflows\");\n _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {\n uint32 blockNumber = safe32(block.number, \"XVS::_writeCheckpoint: block number exceeds 32 bits\");\n\n if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {\n checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n } else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);\n numCheckpoints[delegatee] = nCheckpoints + 1;\n }\n\n emit DelegateVotesChanged(delegatee, oldVotes, newVotes);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n < 2 ** 32, errorMessage);\n return uint32(n);\n }\n\n function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {\n require(n < 2 ** 96, errorMessage);\n return uint96(n);\n }\n\n function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n uint96 c = a + b;\n require(c >= a, errorMessage);\n return c;\n }\n\n function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n function getChainId() internal pure returns (uint) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n return chainId;\n }\n}\n" + }, + "contracts/Tokens/XVS/XVSVesting.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/IBEP20.sol\";\nimport \"../../Utils/SafeBEP20.sol\";\nimport \"./XVSVestingStorage.sol\";\nimport \"./XVSVestingProxy.sol\";\n\n/**\n * @title Venus's XVSVesting Contract\n * @author Venus\n */\ncontract XVSVesting is XVSVestingStorage {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice total vesting period for 1 year in seconds\n uint256 public constant TOTAL_VESTING_TIME = 365 * 24 * 60 * 60;\n\n /// @notice decimal precision for XVS\n uint256 public constant xvsDecimalsMultiplier = 1e18;\n\n /// @notice Emitted when XVSVested is claimed by recipient\n event VestedTokensClaimed(address recipient, uint256 amountClaimed);\n\n /// @notice Emitted when vrtConversionAddress is set\n event VRTConversionSet(address vrtConversionAddress);\n\n /// @notice Emitted when XVS is deposited for vesting\n event XVSVested(address indexed recipient, uint256 startTime, uint256 amount, uint256 withdrawnAmount);\n\n /// @notice Emitted when XVS is withdrawn by recipient\n event XVSWithdrawn(address recipient, uint256 amount);\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n constructor() public {}\n\n /**\n * @notice initialize XVSVestingStorage\n * @param _xvsAddress The XVSToken address\n */\n function initialize(address _xvsAddress) public {\n require(msg.sender == admin, \"only admin may initialize the XVSVesting\");\n require(initialized == false, \"XVSVesting is already initialized\");\n require(_xvsAddress != address(0), \"_xvsAddress cannot be Zero\");\n xvs = IBEP20(_xvsAddress);\n\n _notEntered = true;\n initialized = true;\n }\n\n modifier isInitialized() {\n require(initialized == true, \"XVSVesting is not initialized\");\n _;\n }\n\n /**\n * @notice sets VRTConverter Address\n * @dev Note: If VRTConverter is not set, then Vesting is not allowed\n * @param _vrtConversionAddress The VRTConverterProxy Address\n */\n function setVRTConverter(address _vrtConversionAddress) public {\n require(msg.sender == admin, \"only admin may initialize the Vault\");\n require(_vrtConversionAddress != address(0), \"vrtConversionAddress cannot be Zero\");\n vrtConversionAddress = _vrtConversionAddress;\n emit VRTConversionSet(_vrtConversionAddress);\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n modifier onlyVrtConverter() {\n require(msg.sender == vrtConversionAddress, \"only VRTConversion Address can call the function\");\n _;\n }\n\n modifier vestingExistCheck(address recipient) {\n require(vestings[recipient].length > 0, \"recipient doesnot have any vestingRecord\");\n _;\n }\n\n /**\n * @notice Deposit XVS for Vesting\n * @param recipient The vesting recipient\n * @param depositAmount XVS amount for deposit\n */\n function deposit(\n address recipient,\n uint depositAmount\n ) external isInitialized onlyVrtConverter nonZeroAddress(recipient) {\n require(depositAmount > 0, \"Deposit amount must be non-zero\");\n\n VestingRecord[] storage vestingsOfRecipient = vestings[recipient];\n\n VestingRecord memory vesting = VestingRecord({\n recipient: recipient,\n startTime: getCurrentTime(),\n amount: depositAmount,\n withdrawnAmount: 0\n });\n\n vestingsOfRecipient.push(vesting);\n\n emit XVSVested(recipient, vesting.startTime, vesting.amount, vesting.withdrawnAmount);\n }\n\n /**\n * @notice Withdraw Vested XVS of recipient\n */\n function withdraw() external isInitialized vestingExistCheck(msg.sender) {\n address recipient = msg.sender;\n VestingRecord[] storage vestingsOfRecipient = vestings[recipient];\n uint256 vestingCount = vestingsOfRecipient.length;\n uint256 totalWithdrawableAmount = 0;\n\n for (uint i = 0; i < vestingCount; ++i) {\n VestingRecord storage vesting = vestingsOfRecipient[i];\n (, uint256 toWithdraw) = calculateWithdrawableAmount(\n vesting.amount,\n vesting.startTime,\n vesting.withdrawnAmount\n );\n if (toWithdraw > 0) {\n totalWithdrawableAmount = totalWithdrawableAmount.add(toWithdraw);\n vesting.withdrawnAmount = vesting.withdrawnAmount.add(toWithdraw);\n }\n }\n\n if (totalWithdrawableAmount > 0) {\n uint256 xvsBalance = xvs.balanceOf(address(this));\n require(xvsBalance >= totalWithdrawableAmount, \"Insufficient XVS for withdrawal\");\n emit XVSWithdrawn(recipient, totalWithdrawableAmount);\n xvs.safeTransfer(recipient, totalWithdrawableAmount);\n }\n }\n\n /**\n * @notice get Withdrawable XVS Amount\n * @param recipient The vesting recipient\n * @dev returns A tuple with totalWithdrawableAmount , totalVestedAmount and totalWithdrawnAmount\n */\n function getWithdrawableAmount(\n address recipient\n )\n public\n view\n isInitialized\n nonZeroAddress(recipient)\n vestingExistCheck(recipient)\n returns (uint256 totalWithdrawableAmount, uint256 totalVestedAmount, uint256 totalWithdrawnAmount)\n {\n VestingRecord[] storage vestingsOfRecipient = vestings[recipient];\n uint256 vestingCount = vestingsOfRecipient.length;\n\n for (uint i = 0; i < vestingCount; i++) {\n VestingRecord storage vesting = vestingsOfRecipient[i];\n (uint256 vestedAmount, uint256 toWithdraw) = calculateWithdrawableAmount(\n vesting.amount,\n vesting.startTime,\n vesting.withdrawnAmount\n );\n totalVestedAmount = totalVestedAmount.add(vestedAmount);\n totalWithdrawableAmount = totalWithdrawableAmount.add(toWithdraw);\n totalWithdrawnAmount = totalWithdrawnAmount.add(vesting.withdrawnAmount);\n }\n\n return (totalWithdrawableAmount, totalVestedAmount, totalWithdrawnAmount);\n }\n\n /**\n * @notice get Withdrawable XVS Amount\n * @param amount Amount deposited for vesting\n * @param vestingStartTime time in epochSeconds at the time of vestingDeposit\n * @param withdrawnAmount XVSAmount withdrawn from VestedAmount\n * @dev returns A tuple with vestedAmount and withdrawableAmount\n */\n function calculateWithdrawableAmount(\n uint256 amount,\n uint256 vestingStartTime,\n uint256 withdrawnAmount\n ) internal view returns (uint256, uint256) {\n uint256 vestedAmount = calculateVestedAmount(amount, vestingStartTime, getCurrentTime());\n uint toWithdraw = vestedAmount.sub(withdrawnAmount);\n return (vestedAmount, toWithdraw);\n }\n\n /**\n * @notice calculate total vested amount\n * @param vestingAmount Amount deposited for vesting\n * @param vestingStartTime time in epochSeconds at the time of vestingDeposit\n * @param currentTime currentTime in epochSeconds\n * @return Total XVS amount vested\n */\n function calculateVestedAmount(\n uint256 vestingAmount,\n uint256 vestingStartTime,\n uint256 currentTime\n ) internal view returns (uint256) {\n if (currentTime < vestingStartTime) {\n return 0;\n } else if (currentTime > vestingStartTime.add(TOTAL_VESTING_TIME)) {\n return vestingAmount;\n } else {\n return (vestingAmount.mul(currentTime.sub(vestingStartTime))).div(TOTAL_VESTING_TIME);\n }\n }\n\n /**\n * @notice current block timestamp\n * @return blocktimestamp\n */\n function getCurrentTime() public view returns (uint256) {\n return block.timestamp;\n }\n\n /*** Admin Functions ***/\n function _become(XVSVestingProxy xvsVestingProxy) public {\n require(msg.sender == xvsVestingProxy.admin(), \"only proxy admin can change brains\");\n xvsVestingProxy._acceptImplementation();\n }\n}\n" + }, + "contracts/Tokens/XVS/XVSVestingProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./XVSVestingStorage.sol\";\n\ncontract XVSVestingProxy is XVSVestingAdminStorage {\n /**\n * @notice Emitted when pendingImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingImplementation is accepted, which means XVSVesting implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor(\n address implementation_,\n address _xvsAddress\n ) public nonZeroAddress(implementation_) nonZeroAddress(_xvsAddress) {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_);\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(implementation_, abi.encodeWithSignature(\"initialize(address)\", _xvsAddress));\n }\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n */\n function _setImplementation(address implementation_) public {\n require(msg.sender == admin, \"XVSVestingProxy::_setImplementation: admin only\");\n require(implementation_ != address(0), \"XVSVestingProxy::_setImplementation: invalid implementation address\");\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal nonZeroAddress(callee) returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(\n address newPendingImplementation\n ) public nonZeroAddress(newPendingImplementation) {\n require(msg.sender == admin, \"Only admin can set Pending Implementation\");\n\n address oldPendingImplementation = pendingImplementation;\n\n pendingImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Accepts new implementation of VRT Vault. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n */\n function _acceptImplementation() public {\n // Check caller is pendingImplementation\n require(\n msg.sender == pendingImplementation,\n \"only address marked as pendingImplementation can accept Implementation\"\n );\n\n // Save current values for inclusion in log\n address oldImplementation = implementation;\n address oldPendingImplementation = pendingImplementation;\n\n implementation = pendingImplementation;\n\n pendingImplementation = address(0);\n\n emit NewImplementation(oldImplementation, implementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n */\n function _setPendingAdmin(address newPendingAdmin) public nonZeroAddress(newPendingAdmin) {\n // Check caller = admin\n require(msg.sender == admin, \"only admin can set pending admin\");\n require(newPendingAdmin != pendingAdmin, \"New pendingAdmin can not be same as the previous one\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n */\n function _acceptAdmin() public {\n // Check caller is pendingAdmin\n require(msg.sender == pendingAdmin, \"only address marked as pendingAdmin can accept as Admin\");\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/Tokens/XVS/XVSVestingStorage.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../../Utils/SafeMath.sol\";\nimport \"../../Utils/IBEP20.sol\";\n\ncontract XVSVestingAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of XVSVesting\n */\n address public implementation;\n\n /**\n * @notice Pending brains of XVSVesting\n */\n address public pendingImplementation;\n}\n\ncontract XVSVestingStorage is XVSVestingAdminStorage {\n struct VestingRecord {\n address recipient;\n uint256 startTime;\n uint256 amount;\n uint256 withdrawnAmount;\n }\n\n /// @notice Guard variable for re-entrancy checks\n bool public _notEntered;\n\n /// @notice indicator to check if the contract is initialized\n bool public initialized;\n\n /// @notice The XVS TOKEN!\n IBEP20 public xvs;\n\n /// @notice VRTConversion Contract Address\n address public vrtConversionAddress;\n\n /// @notice mapping of VestingRecord(s) for user(s)\n mapping(address => VestingRecord[]) public vestings;\n}\n" + }, + "contracts/Utils/Address.sol": { + "content": "pragma solidity ^0.5.5;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n codehash := extcodehash(account)\n }\n return (codehash != accountHash && codehash != 0x0);\n }\n\n /**\n * @dev Converts an `address` into `address payable`. Note that this is\n * simply a type cast: the actual underlying value is not changed.\n *\n * _Available since v2.4.0._\n */\n function toPayable(address account) internal pure returns (address payable) {\n return address(uint160(account));\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n *\n * _Available since v2.4.0._\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-call-value\n // solium-disable-next-line security/no-call-value\n (bool success, ) = recipient.call.value(amount)(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/Utils/CarefulMath.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title Careful Math\n * @author Venus\n * @notice Derived from OpenZeppelin's SafeMath library\n * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol\n */\ncontract CarefulMath {\n /**\n * @dev Possible error codes that we can return\n */\n enum MathError {\n NO_ERROR,\n DIVISION_BY_ZERO,\n INTEGER_OVERFLOW,\n INTEGER_UNDERFLOW\n }\n\n /**\n * @dev Multiplies two numbers, returns an error on overflow.\n */\n function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {\n if (a == 0) {\n return (MathError.NO_ERROR, 0);\n }\n\n uint c = a * b;\n\n if (c / a != b) {\n return (MathError.INTEGER_OVERFLOW, 0);\n } else {\n return (MathError.NO_ERROR, c);\n }\n }\n\n /**\n * @dev Integer division of two numbers, truncating the quotient.\n */\n function divUInt(uint a, uint b) internal pure returns (MathError, uint) {\n if (b == 0) {\n return (MathError.DIVISION_BY_ZERO, 0);\n }\n\n return (MathError.NO_ERROR, a / b);\n }\n\n /**\n * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).\n */\n function subUInt(uint a, uint b) internal pure returns (MathError, uint) {\n if (b <= a) {\n return (MathError.NO_ERROR, a - b);\n } else {\n return (MathError.INTEGER_UNDERFLOW, 0);\n }\n }\n\n /**\n * @dev Adds two numbers, returns an error on overflow.\n */\n function addUInt(uint a, uint b) internal pure returns (MathError, uint) {\n uint c = a + b;\n\n if (c >= a) {\n return (MathError.NO_ERROR, c);\n } else {\n return (MathError.INTEGER_OVERFLOW, 0);\n }\n }\n\n /**\n * @dev add a and b and then subtract c\n */\n function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {\n (MathError err0, uint sum) = addUInt(a, b);\n\n if (err0 != MathError.NO_ERROR) {\n return (err0, 0);\n }\n\n return subUInt(sum, c);\n }\n}\n" + }, + "contracts/Utils/Context.sol": { + "content": "pragma solidity ^0.5.16;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\ncontract Context {\n // Empty internal constructor, to prevent people from mistakenly deploying\n // an instance of this contract, which should be used via inheritance.\n constructor() internal {}\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "contracts/Utils/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// Adapted from OpenZeppelin Contracts v4.3.2 (utils/cryptography/ECDSA.sol)\n\n// SPDX-Copyright-Text: OpenZeppelin, 2021\n// SPDX-Copyright-Text: Venus, 2021\n\npragma solidity ^0.5.16;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\ncontract ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n}\n" + }, + "contracts/Utils/ErrorReporter.sol": { + "content": "pragma solidity ^0.5.16;\n\ncontract ComptrollerErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED,\n COMPTROLLER_MISMATCH,\n INSUFFICIENT_SHORTFALL,\n INSUFFICIENT_LIQUIDITY,\n INVALID_CLOSE_FACTOR,\n INVALID_COLLATERAL_FACTOR,\n INVALID_LIQUIDATION_INCENTIVE,\n MARKET_NOT_ENTERED, // no longer possible\n MARKET_NOT_LISTED,\n MARKET_ALREADY_LISTED,\n MATH_ERROR,\n NONZERO_BORROW_BALANCE,\n PRICE_ERROR,\n REJECTION,\n SNAPSHOT_ERROR,\n TOO_MANY_ASSETS,\n TOO_MUCH_REPAY,\n INSUFFICIENT_BALANCE_FOR_VAI,\n MARKET_NOT_COLLATERAL\n }\n\n enum FailureInfo {\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n EXIT_MARKET_BALANCE_OWED,\n EXIT_MARKET_REJECTION,\n SET_CLOSE_FACTOR_OWNER_CHECK,\n SET_CLOSE_FACTOR_VALIDATION,\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\n SET_COLLATERAL_FACTOR_NO_EXISTS,\n SET_COLLATERAL_FACTOR_VALIDATION,\n SET_COLLATERAL_FACTOR_WITHOUT_PRICE,\n SET_IMPLEMENTATION_OWNER_CHECK,\n SET_LIQUIDATION_INCENTIVE_OWNER_CHECK,\n SET_LIQUIDATION_INCENTIVE_VALIDATION,\n SET_MAX_ASSETS_OWNER_CHECK,\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\n SET_PRICE_ORACLE_OWNER_CHECK,\n SUPPORT_MARKET_EXISTS,\n SUPPORT_MARKET_OWNER_CHECK,\n SET_PAUSE_GUARDIAN_OWNER_CHECK,\n SET_VAI_MINT_RATE_CHECK,\n SET_VAICONTROLLER_OWNER_CHECK,\n SET_MINTED_VAI_REJECTION,\n SET_TREASURY_OWNER_CHECK,\n UNLIST_MARKET_NOT_LISTED\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n\ncontract TokenErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED,\n BAD_INPUT,\n COMPTROLLER_REJECTION,\n COMPTROLLER_CALCULATION_ERROR,\n INTEREST_RATE_MODEL_ERROR,\n INVALID_ACCOUNT_PAIR,\n INVALID_CLOSE_AMOUNT_REQUESTED,\n INVALID_COLLATERAL_FACTOR,\n MATH_ERROR,\n MARKET_NOT_FRESH,\n MARKET_NOT_LISTED,\n TOKEN_INSUFFICIENT_ALLOWANCE,\n TOKEN_INSUFFICIENT_BALANCE,\n TOKEN_INSUFFICIENT_CASH,\n TOKEN_TRANSFER_IN_FAILED,\n TOKEN_TRANSFER_OUT_FAILED,\n TOKEN_PRICE_ERROR\n }\n\n /*\n * Note: FailureInfo (but not Error) is kept in alphabetical order\n * This is because FailureInfo grows significantly faster, and\n * the order of Error has some meaning, while the order of FailureInfo\n * is entirely arbitrary.\n */\n enum FailureInfo {\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED,\n ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED,\n ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED,\n ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED,\n ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED,\n ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED,\n BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\n BORROW_ACCRUE_INTEREST_FAILED,\n BORROW_CASH_NOT_AVAILABLE,\n BORROW_FRESHNESS_CHECK,\n BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\n BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\n BORROW_MARKET_NOT_LISTED,\n BORROW_COMPTROLLER_REJECTION,\n LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\n LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\n LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\n LIQUIDATE_COMPTROLLER_REJECTION,\n LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\n LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\n LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\n LIQUIDATE_FRESHNESS_CHECK,\n LIQUIDATE_LIQUIDATOR_IS_BORROWER,\n LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\n LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\n LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\n LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\n LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\n LIQUIDATE_SEIZE_TOO_MUCH,\n MINT_ACCRUE_INTEREST_FAILED,\n MINT_COMPTROLLER_REJECTION,\n MINT_EXCHANGE_CALCULATION_FAILED,\n MINT_EXCHANGE_RATE_READ_FAILED,\n MINT_FRESHNESS_CHECK,\n MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\n MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\n MINT_TRANSFER_IN_FAILED,\n MINT_TRANSFER_IN_NOT_POSSIBLE,\n REDEEM_ACCRUE_INTEREST_FAILED,\n REDEEM_COMPTROLLER_REJECTION,\n REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED,\n REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED,\n REDEEM_EXCHANGE_RATE_READ_FAILED,\n REDEEM_FRESHNESS_CHECK,\n REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED,\n REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,\n REDEEM_TRANSFER_OUT_NOT_POSSIBLE,\n REDUCE_RESERVES_ACCRUE_INTEREST_FAILED,\n REDUCE_RESERVES_ADMIN_CHECK,\n REDUCE_RESERVES_CASH_NOT_AVAILABLE,\n REDUCE_RESERVES_FRESH_CHECK,\n REDUCE_RESERVES_VALIDATION,\n REPAY_BEHALF_ACCRUE_INTEREST_FAILED,\n REPAY_BORROW_ACCRUE_INTEREST_FAILED,\n REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED,\n REPAY_BORROW_COMPTROLLER_REJECTION,\n REPAY_BORROW_FRESHNESS_CHECK,\n REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED,\n REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,\n REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,\n SET_COLLATERAL_FACTOR_OWNER_CHECK,\n SET_COLLATERAL_FACTOR_VALIDATION,\n SET_COMPTROLLER_OWNER_CHECK,\n SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED,\n SET_INTEREST_RATE_MODEL_FRESH_CHECK,\n SET_INTEREST_RATE_MODEL_OWNER_CHECK,\n SET_MAX_ASSETS_OWNER_CHECK,\n SET_ORACLE_MARKET_NOT_LISTED,\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED,\n SET_RESERVE_FACTOR_ADMIN_CHECK,\n SET_RESERVE_FACTOR_FRESH_CHECK,\n SET_RESERVE_FACTOR_BOUNDS_CHECK,\n TRANSFER_COMPTROLLER_REJECTION,\n TRANSFER_NOT_ALLOWED,\n TRANSFER_NOT_ENOUGH,\n TRANSFER_TOO_MUCH,\n ADD_RESERVES_ACCRUE_INTEREST_FAILED,\n ADD_RESERVES_FRESH_CHECK,\n ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE,\n TOKEN_GET_UNDERLYING_PRICE_ERROR,\n REPAY_VAI_COMPTROLLER_REJECTION,\n REPAY_VAI_FRESHNESS_CHECK,\n VAI_MINT_EXCHANGE_CALCULATION_FAILED,\n SFT_MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n\ncontract VAIControllerErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED, // The sender is not authorized to perform this action.\n REJECTION, // The action would violate the comptroller, vaicontroller policy.\n SNAPSHOT_ERROR, // The comptroller could not get the account borrows and exchange rate from the market.\n PRICE_ERROR, // The comptroller could not obtain a required price of an asset.\n MATH_ERROR, // A math calculation error occurred.\n INSUFFICIENT_BALANCE_FOR_VAI // Caller does not have sufficient balance to mint VAI.\n }\n\n enum FailureInfo {\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK,\n SET_COMPTROLLER_OWNER_CHECK,\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n VAI_MINT_REJECTION,\n VAI_BURN_REJECTION,\n VAI_LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED,\n VAI_LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED,\n VAI_LIQUIDATE_COLLATERAL_FRESHNESS_CHECK,\n VAI_LIQUIDATE_COMPTROLLER_REJECTION,\n VAI_LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED,\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX,\n VAI_LIQUIDATE_CLOSE_AMOUNT_IS_ZERO,\n VAI_LIQUIDATE_FRESHNESS_CHECK,\n VAI_LIQUIDATE_LIQUIDATOR_IS_BORROWER,\n VAI_LIQUIDATE_REPAY_BORROW_FRESH_FAILED,\n VAI_LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED,\n VAI_LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED,\n VAI_LIQUIDATE_SEIZE_COMPTROLLER_REJECTION,\n VAI_LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER,\n VAI_LIQUIDATE_SEIZE_TOO_MUCH,\n MINT_FEE_CALCULATION_FAILED,\n SET_TREASURY_OWNER_CHECK\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n" + }, + "contracts/Utils/Exponential.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./CarefulMath.sol\";\nimport \"./ExponentialNoError.sol\";\n\n/**\n * @title Exponential module for storing fixed-precision decimals\n * @author Venus\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\n * `Exp({mantissa: 5100000000000000000})`.\n */\ncontract Exponential is CarefulMath, ExponentialNoError {\n /**\n * @dev Creates an exponential from numerator and denominator values.\n * Note: Returns an error if (`num` * 10e18) > MAX_INT,\n * or if `denom` is zero.\n */\n function getExp(uint num, uint denom) internal pure returns (MathError, Exp memory) {\n (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n\n (MathError err1, uint rational) = divUInt(scaledNumerator, denom);\n if (err1 != MathError.NO_ERROR) {\n return (err1, Exp({ mantissa: 0 }));\n }\n\n return (MathError.NO_ERROR, Exp({ mantissa: rational }));\n }\n\n /**\n * @dev Adds two exponentials, returning a new exponential.\n */\n function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\n (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);\n\n return (error, Exp({ mantissa: result }));\n }\n\n /**\n * @dev Subtracts two exponentials, returning a new exponential.\n */\n function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\n (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);\n\n return (error, Exp({ mantissa: result }));\n }\n\n /**\n * @dev Multiply an Exp by a scalar, returning a new Exp.\n */\n function mulScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\n (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n\n return (MathError.NO_ERROR, Exp({ mantissa: scaledMantissa }));\n }\n\n /**\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\n */\n function mulScalarTruncate(Exp memory a, uint scalar) internal pure returns (MathError, uint) {\n (MathError err, Exp memory product) = mulScalar(a, scalar);\n if (err != MathError.NO_ERROR) {\n return (err, 0);\n }\n\n return (MathError.NO_ERROR, truncate(product));\n }\n\n /**\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\n */\n function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (MathError, uint) {\n (MathError err, Exp memory product) = mulScalar(a, scalar);\n if (err != MathError.NO_ERROR) {\n return (err, 0);\n }\n\n return addUInt(truncate(product), addend);\n }\n\n /**\n * @dev Divide an Exp by a scalar, returning a new Exp.\n */\n function divScalar(Exp memory a, uint scalar) internal pure returns (MathError, Exp memory) {\n (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n\n return (MathError.NO_ERROR, Exp({ mantissa: descaledMantissa }));\n }\n\n /**\n * @dev Divide a scalar by an Exp, returning a new Exp.\n */\n function divScalarByExp(uint scalar, Exp memory divisor) internal pure returns (MathError, Exp memory) {\n /*\n We are doing this as:\n getExp(mulUInt(expScale, scalar), divisor.mantissa)\n\n How it works:\n Exp = a / b;\n Scalar = s;\n `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`\n */\n (MathError err0, uint numerator) = mulUInt(expScale, scalar);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n return getExp(numerator, divisor.mantissa);\n }\n\n /**\n * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.\n */\n function divScalarByExpTruncate(uint scalar, Exp memory divisor) internal pure returns (MathError, uint) {\n (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);\n if (err != MathError.NO_ERROR) {\n return (err, 0);\n }\n\n return (MathError.NO_ERROR, truncate(fraction));\n }\n\n /**\n * @dev Multiplies two exponentials, returning a new exponential.\n */\n function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\n (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);\n if (err0 != MathError.NO_ERROR) {\n return (err0, Exp({ mantissa: 0 }));\n }\n\n // We add half the scale before dividing so that we get rounding instead of truncation.\n // See \"Listing 6\" and text above it at https://accu.org/index.php/journals/1717\n // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.\n (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);\n if (err1 != MathError.NO_ERROR) {\n return (err1, Exp({ mantissa: 0 }));\n }\n\n (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);\n // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.\n assert(err2 == MathError.NO_ERROR);\n\n return (MathError.NO_ERROR, Exp({ mantissa: product }));\n }\n\n /**\n * @dev Multiplies two exponentials given their mantissas, returning a new exponential.\n */\n function mulExp(uint a, uint b) internal pure returns (MathError, Exp memory) {\n return mulExp(Exp({ mantissa: a }), Exp({ mantissa: b }));\n }\n\n /**\n * @dev Multiplies three exponentials, returning a new exponential.\n */\n function mulExp3(Exp memory a, Exp memory b, Exp memory c) internal pure returns (MathError, Exp memory) {\n (MathError err, Exp memory ab) = mulExp(a, b);\n if (err != MathError.NO_ERROR) {\n return (err, ab);\n }\n return mulExp(ab, c);\n }\n\n /**\n * @dev Divides two exponentials, returning a new exponential.\n * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,\n * which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)\n */\n function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) {\n return getExp(a.mantissa, b.mantissa);\n }\n}\n" + }, + "contracts/Utils/ExponentialNoError.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @title Exponential module for storing fixed-precision decimals\n * @author Compound\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\n * `Exp({mantissa: 5100000000000000000})`.\n */\ncontract ExponentialNoError {\n uint internal constant expScale = 1e18;\n uint internal constant doubleScale = 1e36;\n uint internal constant halfExpScale = expScale / 2;\n uint internal constant mantissaOne = expScale;\n\n struct Exp {\n uint mantissa;\n }\n\n struct Double {\n uint mantissa;\n }\n\n /**\n * @dev Truncates the given exp to a whole number value.\n * For example, truncate(Exp{mantissa: 15 * expScale}) = 15\n */\n function truncate(Exp memory exp) internal pure returns (uint) {\n // Note: We are not using careful math here as we're performing a division that cannot fail\n return exp.mantissa / expScale;\n }\n\n /**\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\n */\n function mul_ScalarTruncate(Exp memory a, uint scalar) internal pure returns (uint) {\n Exp memory product = mul_(a, scalar);\n return truncate(product);\n }\n\n /**\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\n */\n function mul_ScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) internal pure returns (uint) {\n Exp memory product = mul_(a, scalar);\n return add_(truncate(product), addend);\n }\n\n /**\n * @dev Checks if first Exp is less than second Exp.\n */\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\n return left.mantissa < right.mantissa;\n }\n\n /**\n * @dev Checks if left Exp <= right Exp.\n */\n function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {\n return left.mantissa <= right.mantissa;\n }\n\n /**\n * @dev Checks if left Exp > right Exp.\n */\n function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\n return left.mantissa > right.mantissa;\n }\n\n /**\n * @dev returns true if Exp is exactly zero\n */\n function isZeroExp(Exp memory value) internal pure returns (bool) {\n return value.mantissa == 0;\n }\n\n function safe224(uint n, string memory errorMessage) internal pure returns (uint224) {\n require(n < 2 ** 224, errorMessage);\n return uint224(n);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n < 2 ** 32, errorMessage);\n return uint32(n);\n }\n\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\n }\n\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\n }\n\n function add_(uint a, uint b) internal pure returns (uint) {\n return add_(a, b, \"addition overflow\");\n }\n\n function add_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\n uint c = a + b;\n require(c >= a, errorMessage);\n return c;\n }\n\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\n }\n\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\n }\n\n function sub_(uint a, uint b) internal pure returns (uint) {\n return sub_(a, b, \"subtraction underflow\");\n }\n\n function sub_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / expScale });\n }\n\n function mul_(Exp memory a, uint b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint a, Exp memory b) internal pure returns (uint) {\n return mul_(a, b.mantissa) / expScale;\n }\n\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / doubleScale });\n }\n\n function mul_(Double memory a, uint b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint a, Double memory b) internal pure returns (uint) {\n return mul_(a, b.mantissa) / doubleScale;\n }\n\n function mul_(uint a, uint b) internal pure returns (uint) {\n return mul_(a, b, \"multiplication overflow\");\n }\n\n function mul_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\n if (a == 0 || b == 0) {\n return 0;\n }\n uint c = a * b;\n require(c / a == b, errorMessage);\n return c;\n }\n\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(mul_(a.mantissa, expScale), b.mantissa) });\n }\n\n function div_(Exp memory a, uint b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint a, Exp memory b) internal pure returns (uint) {\n return div_(mul_(a, expScale), b.mantissa);\n }\n\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a.mantissa, doubleScale), b.mantissa) });\n }\n\n function div_(Double memory a, uint b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint a, Double memory b) internal pure returns (uint) {\n return div_(mul_(a, doubleScale), b.mantissa);\n }\n\n function div_(uint a, uint b) internal pure returns (uint) {\n return div_(a, b, \"divide by zero\");\n }\n\n function div_(uint a, uint b, string memory errorMessage) internal pure returns (uint) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n function fraction(uint a, uint b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a, doubleScale), b) });\n }\n}\n" + }, + "contracts/Utils/IBEP20.sol": { + "content": "pragma solidity ^0.5.0;\n\n/**\n * @dev Interface of the BEP20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {BEP20Detailed}.\n */\ninterface IBEP20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "contracts/Utils/Ownable.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "contracts/Utils/Owned.sol": { + "content": "pragma solidity ^0.5.16;\n\ncontract Owned {\n address public owner;\n\n event OwnershipTransferred(address indexed _from, address indexed _to);\n\n constructor() public {\n owner = msg.sender;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Should be owner\");\n _;\n }\n\n function transferOwnership(address newOwner) public onlyOwner {\n owner = newOwner;\n emit OwnershipTransferred(owner, newOwner);\n }\n}\n" + }, + "contracts/Utils/SafeBEP20.sol": { + "content": "pragma solidity ^0.5.0;\n\nimport \"./SafeMath.sol\";\nimport \"./IBEP20.sol\";\nimport \"./Address.sol\";\n\n/**\n * @title SafeBEP20\n * @dev Wrappers around BEP20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeBEP20 for BEP20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeBEP20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IBEP20 token, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IBEP20 token, address from, address to, uint256 value) internal {\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n function safeApprove(IBEP20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeBEP20: approve from non-zero to non-zero allowance\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IBEP20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(\n value,\n \"SafeBEP20: decreased allowance below zero\"\n );\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function callOptionalReturn(IBEP20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves.\n\n // A Solidity high level call has three parts:\n // 1. The target address is checked to verify it contains contract code\n // 2. The call itself is made, and success asserted\n // 3. The return value is decoded, which in turn checks the size of the returned data.\n // solhint-disable-next-line max-line-length\n require(address(token).isContract(), \"SafeBEP20: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = address(token).call(data);\n require(success, \"SafeBEP20: low-level call failed\");\n\n if (returndata.length > 0) {\n // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeBEP20: BEP20 operation did not succeed\");\n }\n }\n}\n" + }, + "contracts/Utils/SafeCast.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2 ** 128, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2 ** 64, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2 ** 32, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2 ** 16, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2 ** 8, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2 ** 127 && value < 2 ** 127, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2 ** 63 && value < 2 ** 63, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2 ** 31 && value < 2 ** 31, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2 ** 15 && value < 2 ** 15, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2 ** 7 && value < 2 ** 7, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2 ** 255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/Utils/SafeMath.sol": { + "content": "pragma solidity ^0.5.16;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return add(a, b, \"SafeMath: addition overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, errorMessage);\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/Utils/Tokenlock.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./Owned.sol\";\n\ncontract Tokenlock is Owned {\n /// @notice Indicates if token is locked\n uint8 internal isLocked = 0;\n\n event Freezed();\n event UnFreezed();\n\n modifier validLock() {\n require(isLocked == 0, \"Token is locked\");\n _;\n }\n\n function freeze() public onlyOwner {\n isLocked = 1;\n\n emit Freezed();\n }\n\n function unfreeze() public onlyOwner {\n isLocked = 0;\n\n emit UnFreezed();\n }\n}\n" + }, + "contracts/VAIVault/VAIVault.sol": { + "content": "pragma solidity 0.5.16;\n\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/IBEP20.sol\";\nimport \"./VAIVaultStorage.sol\";\nimport \"./VAIVaultErrorReporter.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV5.sol\";\nimport { VAIVaultProxy } from \"./VAIVaultProxy.sol\";\n\n/**\n * @title VAI Vault\n * @author Venus\n * @notice The VAI Vault is configured for users to stake VAI And receive XVS as a reward.\n */\ncontract VAIVault is VAIVaultStorage, AccessControlledV5 {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice Event emitted when VAI deposit\n event Deposit(address indexed user, uint256 amount);\n\n /// @notice Event emitted when VAI withrawal\n event Withdraw(address indexed user, uint256 amount);\n\n /// @notice Event emitted when vault is paused\n event VaultPaused(address indexed admin);\n\n /// @notice Event emitted when vault is resumed after pause\n event VaultResumed(address indexed admin);\n\n constructor() public {\n admin = msg.sender;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n /*** Reentrancy Guard ***/\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n /**\n * @dev Prevents functions to execute when vault is paused.\n */\n modifier isActive() {\n require(!vaultPaused, \"Vault is paused\");\n _;\n }\n\n /**\n * @notice Pause vault\n */\n function pause() external {\n _checkAccessAllowed(\"pause()\");\n require(!vaultPaused, \"Vault is already paused\");\n vaultPaused = true;\n emit VaultPaused(msg.sender);\n }\n\n /**\n * @notice Resume vault\n */\n function resume() external {\n _checkAccessAllowed(\"resume()\");\n require(vaultPaused, \"Vault is not paused\");\n vaultPaused = false;\n emit VaultResumed(msg.sender);\n }\n\n /**\n * @notice Deposit VAI to VAIVault for XVS allocation\n * @param _amount The amount to deposit to vault\n */\n function deposit(uint256 _amount) external nonReentrant isActive {\n UserInfo storage user = userInfo[msg.sender];\n\n updateVault();\n\n // Transfer pending tokens to user\n updateAndPayOutPending(msg.sender);\n\n // Transfer in the amounts from user\n if (_amount > 0) {\n vai.safeTransferFrom(address(msg.sender), address(this), _amount);\n user.amount = user.amount.add(_amount);\n }\n\n user.rewardDebt = user.amount.mul(accXVSPerShare).div(1e18);\n emit Deposit(msg.sender, _amount);\n }\n\n /**\n * @notice Withdraw VAI from VAIVault\n * @param _amount The amount to withdraw from vault\n */\n function withdraw(uint256 _amount) external nonReentrant isActive {\n _withdraw(msg.sender, _amount);\n }\n\n /**\n * @notice Claim XVS from VAIVault\n */\n function claim() external nonReentrant isActive {\n _withdraw(msg.sender, 0);\n }\n\n /**\n * @notice Claim XVS from VAIVault\n * @param account The account for which to claim XVS\n */\n function claim(address account) external nonReentrant isActive {\n _withdraw(account, 0);\n }\n\n /**\n * @notice Low level withdraw function\n * @param account The account to withdraw from vault\n * @param _amount The amount to withdraw from vault\n */\n function _withdraw(address account, uint256 _amount) internal {\n UserInfo storage user = userInfo[account];\n require(user.amount >= _amount, \"withdraw: not good\");\n\n updateVault();\n updateAndPayOutPending(account); // Update balances of account this is not withdrawal but claiming XVS farmed\n\n if (_amount > 0) {\n user.amount = user.amount.sub(_amount);\n vai.safeTransfer(address(account), _amount);\n }\n user.rewardDebt = user.amount.mul(accXVSPerShare).div(1e18);\n\n emit Withdraw(account, _amount);\n }\n\n /**\n * @notice View function to see pending XVS on frontend\n * @param _user The user to see pending XVS\n * @return Amount of XVS the user can claim\n */\n function pendingXVS(address _user) public view returns (uint256) {\n UserInfo storage user = userInfo[_user];\n\n return user.amount.mul(accXVSPerShare).div(1e18).sub(user.rewardDebt);\n }\n\n /**\n * @notice Update and pay out pending XVS to user\n * @param account The user to pay out\n */\n function updateAndPayOutPending(address account) internal {\n uint256 pending = pendingXVS(account);\n\n if (pending > 0) {\n safeXVSTransfer(account, pending);\n }\n }\n\n /**\n * @notice Safe XVS transfer function, just in case if rounding error causes pool to not have enough XVS\n * @param _to The address that XVS to be transfered\n * @param _amount The amount that XVS to be transfered\n */\n function safeXVSTransfer(address _to, uint256 _amount) internal {\n uint256 xvsBal = xvs.balanceOf(address(this));\n\n if (_amount > xvsBal) {\n xvs.transfer(_to, xvsBal);\n xvsBalance = xvs.balanceOf(address(this));\n } else {\n xvs.transfer(_to, _amount);\n xvsBalance = xvs.balanceOf(address(this));\n }\n }\n\n /**\n * @notice Function that updates pending rewards\n */\n function updatePendingRewards() public isActive {\n uint256 newRewards = xvs.balanceOf(address(this)).sub(xvsBalance);\n\n if (newRewards > 0) {\n xvsBalance = xvs.balanceOf(address(this)); // If there is no change the balance didn't change\n pendingRewards = pendingRewards.add(newRewards);\n }\n }\n\n /**\n * @notice Update reward variables to be up-to-date\n */\n function updateVault() internal {\n updatePendingRewards();\n\n uint256 vaiBalance = vai.balanceOf(address(this));\n if (vaiBalance == 0) {\n // avoids division by 0 errors\n return;\n }\n\n accXVSPerShare = accXVSPerShare.add(pendingRewards.mul(1e18).div(vaiBalance));\n pendingRewards = 0;\n }\n\n /*** Admin Functions ***/\n\n function _become(VAIVaultProxy vaiVaultProxy) external {\n require(msg.sender == vaiVaultProxy.admin(), \"only proxy admin can change brains\");\n require(vaiVaultProxy._acceptImplementation() == 0, \"change not authorized\");\n }\n\n function setVenusInfo(address _xvs, address _vai) external onlyAdmin {\n require(_xvs != address(0) && _vai != address(0), \"addresses must not be zero\");\n require(address(xvs) == address(0) && address(vai) == address(0), \"addresses already set\");\n xvs = IBEP20(_xvs);\n vai = IBEP20(_vai);\n\n _notEntered = true;\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlAddress New address for the access control\n */\n function setAccessControl(address newAccessControlAddress) external onlyAdmin {\n _setAccessControlManager(newAccessControlAddress);\n }\n}\n" + }, + "contracts/VAIVault/VAIVaultErrorReporter.sol": { + "content": "pragma solidity ^0.5.16;\n\ncontract VAIVaultErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED\n }\n\n enum FailureInfo {\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n" + }, + "contracts/VAIVault/VAIVaultProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VAIVaultStorage.sol\";\nimport \"./VAIVaultErrorReporter.sol\";\n\n/**\n * @title VAI Vault Proxy\n * @author Venus\n * @notice Proxy contract for the VAI Vault\n */\ncontract VAIVaultProxy is VAIVaultAdminStorage, VAIVaultErrorReporter {\n /**\n * @notice Emitted when pendingVAIVaultImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingVAIVaultImplementation is accepted, which means VAI Vault implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor() public {\n // Set admin to caller\n admin = msg.sender;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public returns (uint) {\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK);\n }\n\n address oldPendingImplementation = pendingVAIVaultImplementation;\n\n pendingVAIVaultImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingVAIVaultImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts new implementation of VAI Vault. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public returns (uint) {\n // Check caller is pendingImplementation\n if (msg.sender != pendingVAIVaultImplementation) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldImplementation = vaiVaultImplementation;\n address oldPendingImplementation = pendingVAIVaultImplementation;\n\n vaiVaultImplementation = pendingVAIVaultImplementation;\n\n pendingVAIVaultImplementation = address(0);\n\n emit NewImplementation(oldImplementation, vaiVaultImplementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingVAIVaultImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public returns (uint) {\n // Check caller = admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK);\n }\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public returns (uint) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = vaiVaultImplementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/VAIVault/VAIVaultStorage.sol": { + "content": "pragma solidity ^0.5.16;\nimport \"../Utils/SafeMath.sol\";\nimport \"../Utils/IBEP20.sol\";\n\ncontract VAIVaultAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of VAI Vault\n */\n address public vaiVaultImplementation;\n\n /**\n * @notice Pending brains of VAI Vault\n */\n address public pendingVAIVaultImplementation;\n}\n\ncontract VAIVaultStorage is VAIVaultAdminStorage {\n /// @notice The XVS TOKEN!\n IBEP20 public xvs;\n\n /// @notice The VAI TOKEN!\n IBEP20 public vai;\n\n /// @notice Guard variable for re-entrancy checks\n bool internal _notEntered;\n\n /// @notice XVS balance of vault\n uint256 public xvsBalance;\n\n /// @notice Accumulated XVS per share\n uint256 public accXVSPerShare;\n\n //// pending rewards awaiting anyone to update\n uint256 public pendingRewards;\n\n /// @notice Info of each user.\n struct UserInfo {\n uint256 amount;\n uint256 rewardDebt;\n }\n\n // Info of each user that stakes tokens.\n mapping(address => UserInfo) public userInfo;\n\n /// @notice pause indicator for Vault\n bool public vaultPaused;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/VRTVault/VRTVault.sol": { + "content": "pragma solidity 0.5.16;\n\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/IBEP20.sol\";\nimport \"./VRTVaultStorage.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV5.sol\";\n\ninterface IVRTVaultProxy {\n function _acceptImplementation() external;\n\n function admin() external returns (address);\n}\n\ncontract VRTVault is VRTVaultStorage, AccessControlledV5 {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice The upper bound for lastAccruingBlock. Close to year 3,000, considering 3 seconds per block. Used to avoid a value absurdly high\n uint256 public constant MAX_LAST_ACCRUING_BLOCK = 9999999999;\n\n /// @notice Event emitted when vault is paused\n event VaultPaused(address indexed admin);\n\n /// @notice Event emitted when vault is resumed after pause\n event VaultResumed(address indexed admin);\n\n /// @notice Event emitted on VRT deposit\n event Deposit(address indexed user, uint256 amount);\n\n /// @notice Event emitted when accruedInterest and VRT PrincipalAmount is withrawn\n event Withdraw(\n address indexed user,\n uint256 withdrawnAmount,\n uint256 totalPrincipalAmount,\n uint256 accruedInterest\n );\n\n /// @notice Event emitted when Admin withdraw BEP20 token from contract\n event WithdrawToken(address indexed tokenAddress, address indexed receiver, uint256 amount);\n\n /// @notice Event emitted when accruedInterest is claimed\n event Claim(address indexed user, uint256 interestAmount);\n\n /// @notice Event emitted when lastAccruingBlock state variable changes\n event LastAccruingBlockChanged(uint256 oldLastAccruingBlock, uint256 newLastAccruingBlock);\n\n constructor() public {\n admin = msg.sender;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin allowed\");\n _;\n }\n\n function initialize(address _vrtAddress, uint256 _interestRatePerBlock) public {\n require(msg.sender == admin, \"only admin may initialize the Vault\");\n require(_vrtAddress != address(0), \"vrtAddress cannot be Zero\");\n require(interestRatePerBlock == 0, \"Vault may only be initialized once\");\n\n // Set initial exchange rate\n interestRatePerBlock = _interestRatePerBlock;\n require(interestRatePerBlock > 0, \"interestRate Per Block must be greater than zero.\");\n\n // Set the VRT\n vrt = IBEP20(_vrtAddress);\n _notEntered = true;\n }\n\n modifier isInitialized() {\n require(interestRatePerBlock > 0, \"Vault is not initialized\");\n _;\n }\n\n modifier isActive() {\n require(!vaultPaused, \"Vault is paused\");\n _;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n modifier nonZeroAddress(address _address) {\n require(_address != address(0), \"Address cannot be Zero\");\n _;\n }\n\n modifier userHasPosition(address userAddress) {\n UserInfo storage user = userInfo[userAddress];\n require(user.userAddress != address(0), \"User does not have any position in the Vault.\");\n _;\n }\n\n /**\n * @notice Pause vault\n */\n function pause() external {\n _checkAccessAllowed(\"pause()\");\n require(!vaultPaused, \"Vault is already paused\");\n vaultPaused = true;\n emit VaultPaused(msg.sender);\n }\n\n /**\n * @notice Resume vault\n */\n function resume() external {\n _checkAccessAllowed(\"resume()\");\n require(vaultPaused, \"Vault is not paused\");\n vaultPaused = false;\n emit VaultResumed(msg.sender);\n }\n\n /**\n * @notice Deposit VRT to VRTVault for a fixed-interest-rate\n * @param depositAmount The amount to deposit to vault\n */\n function deposit(uint256 depositAmount) external nonReentrant isInitialized isActive {\n require(depositAmount > 0, \"Deposit amount must be non-zero\");\n\n address userAddress = msg.sender;\n UserInfo storage user = userInfo[userAddress];\n\n if (user.userAddress == address(0)) {\n user.userAddress = userAddress;\n user.totalPrincipalAmount = depositAmount;\n } else {\n // accrue Interest and transfer to the user\n uint256 accruedInterest = computeAccruedInterest(user.totalPrincipalAmount, user.accrualStartBlockNumber);\n\n user.totalPrincipalAmount = user.totalPrincipalAmount.add(depositAmount);\n\n if (accruedInterest > 0) {\n uint256 vrtBalance = vrt.balanceOf(address(this));\n require(\n vrtBalance >= accruedInterest,\n \"Failed to transfer accruedInterest, Insufficient VRT in Vault.\"\n );\n emit Claim(userAddress, accruedInterest);\n vrt.safeTransfer(user.userAddress, accruedInterest);\n }\n }\n\n uint256 currentBlock_ = getBlockNumber();\n if (lastAccruingBlock > currentBlock_) {\n user.accrualStartBlockNumber = currentBlock_;\n } else {\n user.accrualStartBlockNumber = lastAccruingBlock;\n }\n emit Deposit(userAddress, depositAmount);\n vrt.safeTransferFrom(userAddress, address(this), depositAmount);\n }\n\n /**\n * @notice get accruedInterest of the user's VRTDeposits in the Vault\n * @param userAddress Address of User in the the Vault\n * @return The interest accrued, in VRT\n */\n function getAccruedInterest(\n address userAddress\n ) public view nonZeroAddress(userAddress) isInitialized returns (uint256) {\n UserInfo storage user = userInfo[userAddress];\n if (user.accrualStartBlockNumber == 0) {\n return 0;\n }\n\n return computeAccruedInterest(user.totalPrincipalAmount, user.accrualStartBlockNumber);\n }\n\n /**\n * @notice get accruedInterest of the user's VRTDeposits in the Vault\n * @param totalPrincipalAmount of the User\n * @param accrualStartBlockNumber of the User\n * @return The interest accrued, in VRT\n */\n function computeAccruedInterest(\n uint256 totalPrincipalAmount,\n uint256 accrualStartBlockNumber\n ) internal view isInitialized returns (uint256) {\n uint256 blockNumber = getBlockNumber();\n uint256 _lastAccruingBlock = lastAccruingBlock;\n\n if (blockNumber > _lastAccruingBlock) {\n blockNumber = _lastAccruingBlock;\n }\n\n if (accrualStartBlockNumber == 0 || accrualStartBlockNumber >= blockNumber) {\n return 0;\n }\n\n // Number of blocks since deposit\n uint256 blockDelta = blockNumber.sub(accrualStartBlockNumber);\n uint256 accruedInterest = (totalPrincipalAmount.mul(interestRatePerBlock).mul(blockDelta)).div(1e18);\n return accruedInterest;\n }\n\n /**\n * @notice claim the accruedInterest of the user's VRTDeposits in the Vault\n */\n function claim() external nonReentrant isInitialized userHasPosition(msg.sender) isActive {\n _claim(msg.sender);\n }\n\n /**\n * @notice claim the accruedInterest of the user's VRTDeposits in the Vault\n * @param account The account for which to claim rewards\n */\n function claim(address account) external nonReentrant isInitialized userHasPosition(account) isActive {\n _claim(account);\n }\n\n /**\n * @notice Low level claim function\n * @param account The account for which to claim rewards\n */\n function _claim(address account) internal {\n uint256 accruedInterest = getAccruedInterest(account);\n if (accruedInterest > 0) {\n UserInfo storage user = userInfo[account];\n uint256 vrtBalance = vrt.balanceOf(address(this));\n require(vrtBalance >= accruedInterest, \"Failed to transfer VRT, Insufficient VRT in Vault.\");\n emit Claim(account, accruedInterest);\n uint256 currentBlock_ = getBlockNumber();\n if (lastAccruingBlock > currentBlock_) {\n user.accrualStartBlockNumber = currentBlock_;\n } else {\n user.accrualStartBlockNumber = lastAccruingBlock;\n }\n vrt.safeTransfer(user.userAddress, accruedInterest);\n }\n }\n\n /**\n * @notice withdraw accruedInterest and totalPrincipalAmount of the user's VRTDeposit in the Vault\n */\n function withdraw() external nonReentrant isInitialized userHasPosition(msg.sender) isActive {\n address userAddress = msg.sender;\n uint256 accruedInterest = getAccruedInterest(userAddress);\n\n UserInfo storage user = userInfo[userAddress];\n\n uint256 totalPrincipalAmount = user.totalPrincipalAmount;\n uint256 vrtForWithdrawal = accruedInterest.add(totalPrincipalAmount);\n user.totalPrincipalAmount = 0;\n user.accrualStartBlockNumber = getBlockNumber();\n\n uint256 vrtBalance = vrt.balanceOf(address(this));\n require(vrtBalance >= vrtForWithdrawal, \"Failed to transfer VRT, Insufficient VRT in Vault.\");\n\n emit Withdraw(userAddress, vrtForWithdrawal, totalPrincipalAmount, accruedInterest);\n vrt.safeTransfer(user.userAddress, vrtForWithdrawal);\n }\n\n /**\n * @notice withdraw BEP20 tokens from the contract to a recipient address.\n * @param tokenAddress address of the BEP20 token\n * @param receiver recipient of the BEP20 token\n * @param amount tokenAmount\n */\n function withdrawBep20(\n address tokenAddress,\n address receiver,\n uint256 amount\n ) external isInitialized nonZeroAddress(tokenAddress) nonZeroAddress(receiver) {\n _checkAccessAllowed(\"withdrawBep20(address,address,uint256)\");\n require(amount > 0, \"amount is invalid\");\n IBEP20 token = IBEP20(tokenAddress);\n require(amount <= token.balanceOf(address(this)), \"Insufficient amount in Vault\");\n emit WithdrawToken(tokenAddress, receiver, amount);\n token.safeTransfer(receiver, amount);\n }\n\n function setLastAccruingBlock(uint256 _lastAccruingBlock) external {\n _checkAccessAllowed(\"setLastAccruingBlock(uint256)\");\n require(_lastAccruingBlock < MAX_LAST_ACCRUING_BLOCK, \"_lastAccruingBlock is absurdly high\");\n\n uint256 oldLastAccruingBlock = lastAccruingBlock;\n uint256 currentBlock = getBlockNumber();\n if (oldLastAccruingBlock != 0) {\n require(currentBlock < oldLastAccruingBlock, \"Cannot change at this point\");\n }\n if (oldLastAccruingBlock == 0 || _lastAccruingBlock < oldLastAccruingBlock) {\n // Must be in future\n require(currentBlock < _lastAccruingBlock, \"Invalid _lastAccruingBlock interest have been accumulated\");\n }\n lastAccruingBlock = _lastAccruingBlock;\n emit LastAccruingBlockChanged(oldLastAccruingBlock, _lastAccruingBlock);\n }\n\n function getBlockNumber() public view returns (uint256) {\n return block.number;\n }\n\n /*** Admin Functions ***/\n\n function _become(IVRTVaultProxy vrtVaultProxy) external {\n require(msg.sender == vrtVaultProxy.admin(), \"only proxy admin can change brains\");\n vrtVaultProxy._acceptImplementation();\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlAddress New address for the access control\n */\n function setAccessControl(address newAccessControlAddress) external onlyAdmin {\n _setAccessControlManager(newAccessControlAddress);\n }\n}\n" + }, + "contracts/VRTVault/VRTVaultProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./VRTVaultStorage.sol\";\n\ncontract VRTVaultProxy is VRTVaultAdminStorage {\n /**\n * @notice Emitted when pendingImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingImplementation is accepted, which means VRT Vault implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor(address implementation_, address vrtAddress_, uint256 interestRatePerBlock_) public {\n // Creator of the contract is admin during initialization\n admin = msg.sender;\n\n // New implementations always get set via the settor (post-initialize)\n _setImplementation(implementation_);\n\n // First delegate gets to initialize the delegator (i.e. storage contract)\n delegateTo(\n implementation_,\n abi.encodeWithSignature(\"initialize(address,uint256)\", vrtAddress_, interestRatePerBlock_)\n );\n }\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n */\n function _setImplementation(address implementation_) public {\n require(msg.sender == admin, \"VRTVaultProxy::_setImplementation: admin only\");\n require(implementation_ != address(0), \"VRTVaultProxy::_setImplementation: invalid implementation address\");\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n * @return The returned bytes from the delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal returns (bytes memory) {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize)\n }\n }\n return returnData;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public {\n require(msg.sender == admin, \"Only admin can set Pending Implementation\");\n\n address oldPendingImplementation = pendingImplementation;\n\n pendingImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Accepts new implementation of VRT Vault. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n */\n function _acceptImplementation() public {\n // Check caller is pendingImplementation\n require(\n msg.sender == pendingImplementation,\n \"only address marked as pendingImplementation can accept Implementation\"\n );\n\n // Save current values for inclusion in log\n address oldImplementation = implementation;\n address oldPendingImplementation = pendingImplementation;\n\n implementation = pendingImplementation;\n\n pendingImplementation = address(0);\n\n emit NewImplementation(oldImplementation, implementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingImplementation);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n */\n function _setPendingAdmin(address newPendingAdmin) public {\n // Check caller = admin\n require(msg.sender == admin, \"only admin can set pending admin\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @dev return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public {\n // Check caller is pendingAdmin\n require(msg.sender == pendingAdmin, \"only address marked as pendingAdmin can accept as Admin\");\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/VRTVault/VRTVaultStorage.sol": { + "content": "pragma solidity ^0.5.16;\nimport \"../Utils/SafeMath.sol\";\nimport \"../Utils/IBEP20.sol\";\n\ncontract VRTVaultAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of VRT Vault\n */\n address public implementation;\n\n /**\n * @notice Pending brains of VAI Vault\n */\n address public pendingImplementation;\n}\n\ncontract VRTVaultStorage is VRTVaultAdminStorage {\n /// @notice Guard variable for re-entrancy checks\n bool public _notEntered;\n\n /// @notice pause indicator for Vault\n bool public vaultPaused;\n\n /// @notice The VRT TOKEN!\n IBEP20 public vrt;\n\n /// @notice interestRate for accrual - per Block\n uint256 public interestRatePerBlock;\n\n /// @notice Info of each user.\n struct UserInfo {\n address userAddress;\n uint256 accrualStartBlockNumber;\n uint256 totalPrincipalAmount;\n uint256 lastWithdrawnBlockNumber;\n }\n\n // Info of each user that stakes tokens.\n mapping(address => UserInfo) public userInfo;\n\n /// @notice block number after which no interest will be accrued\n uint256 public lastAccruingBlock;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "contracts/XVSVault/XVSStore.sol": { + "content": "pragma solidity 0.5.16;\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/IBEP20.sol\";\n\n/**\n * @title XVS Store\n * @author Venus\n * @notice XVS Store responsible for distributing XVS rewards\n */\ncontract XVSStore {\n using SafeMath for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice The Admin Address\n address public admin;\n\n /// @notice The pending admin address\n address public pendingAdmin;\n\n /// @notice The Owner Address\n address public owner;\n\n /// @notice The reward tokens\n mapping(address => bool) public rewardTokens;\n\n /// @notice Emitted when pendingAdmin is changed\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /// @notice Event emitted when admin changed\n event AdminTransferred(address indexed oldAdmin, address indexed newAdmin);\n\n /// @notice Event emitted when owner changed\n event OwnerTransferred(address indexed oldOwner, address indexed newOwner);\n\n constructor() public {\n admin = msg.sender;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"only owner can\");\n _;\n }\n\n /**\n * @notice Safely transfer rewards. Only active reward tokens can be sent using this function.\n * Only callable by owner\n * @dev Safe reward token transfer function, just in case if rounding error causes pool to not have enough tokens.\n * @param token Reward token to transfer\n * @param _to Destination address of the reward\n * @param _amount Amount to transfer\n */\n function safeRewardTransfer(address token, address _to, uint256 _amount) external onlyOwner {\n require(rewardTokens[token] == true, \"only reward token can\");\n\n if (address(token) != address(0)) {\n uint256 tokenBalance = IBEP20(token).balanceOf(address(this));\n if (_amount > tokenBalance) {\n IBEP20(token).safeTransfer(_to, tokenBalance);\n } else {\n IBEP20(token).safeTransfer(_to, _amount);\n }\n }\n }\n\n /**\n * @notice Allows the admin to propose a new admin\n * Only callable admin\n * @param _admin Propose an account as admin of the XVS store\n */\n function setPendingAdmin(address _admin) external onlyAdmin {\n address oldPendingAdmin = pendingAdmin;\n pendingAdmin = _admin;\n emit NewPendingAdmin(oldPendingAdmin, _admin);\n }\n\n /**\n * @notice Allows an account that is pending as admin to accept the role\n * nly calllable by the pending admin\n */\n function acceptAdmin() external {\n require(msg.sender == pendingAdmin, \"only pending admin\");\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n admin = pendingAdmin;\n pendingAdmin = address(0);\n\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n emit AdminTransferred(oldAdmin, admin);\n }\n\n /**\n * @notice Set the contract owner\n * @param _owner The address of the owner to set\n * Only callable admin\n */\n function setNewOwner(address _owner) external onlyAdmin {\n require(_owner != address(0), \"new owner is the zero address\");\n address oldOwner = owner;\n owner = _owner;\n emit OwnerTransferred(oldOwner, _owner);\n }\n\n /**\n * @notice Set or disable a reward token\n * @param _tokenAddress The address of a token to set as active or inactive\n * @param status Set whether a reward token is active or not\n */\n function setRewardToken(address _tokenAddress, bool status) external {\n require(msg.sender == admin || msg.sender == owner, \"only admin or owner can\");\n rewardTokens[_tokenAddress] = status;\n }\n\n /**\n * @notice Security function to allow the owner of the contract to withdraw from the contract\n * @param _tokenAddress Reward token address to withdraw\n * @param _amount Amount of token to withdraw\n */\n function emergencyRewardWithdraw(address _tokenAddress, uint256 _amount) external onlyOwner {\n IBEP20(_tokenAddress).safeTransfer(address(msg.sender), _amount);\n }\n}\n" + }, + "contracts/XVSVault/XVSVault.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"../Utils/ECDSA.sol\";\nimport \"../Utils/SafeBEP20.sol\";\nimport \"../Utils/IBEP20.sol\";\nimport \"./XVSVaultStorage.sol\";\nimport \"./XVSVaultErrorReporter.sol\";\nimport \"../Tokens/Prime/IPrime.sol\";\nimport \"../Utils/SafeCast.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV5.sol\";\nimport \"@venusprotocol/solidity-utilities/contracts/TimeManagerV5.sol\";\n\nimport { XVSStore } from \"./XVSStore.sol\";\nimport { XVSVaultProxy } from \"./XVSVaultProxy.sol\";\n\n/**\n * @title XVS Vault\n * @author Venus\n * @notice The XVS Vault allows XVS holders to lock their XVS to recieve voting rights in Venus governance and are rewarded with XVS.\n */\ncontract XVSVault is XVSVaultStorage, ECDSA, AccessControlledV5, TimeManagerV5 {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeBEP20 for IBEP20;\n\n /// @notice The upper bound for the lock period in a pool, 10 years\n uint256 public constant MAX_LOCK_PERIOD = 60 * 60 * 24 * 365 * 10;\n\n /// @notice Event emitted when deposit\n event Deposit(address indexed user, address indexed rewardToken, uint256 indexed pid, uint256 amount);\n\n /// @notice Event emitted when execute withrawal\n event ExecutedWithdrawal(address indexed user, address indexed rewardToken, uint256 indexed pid, uint256 amount);\n\n /// @notice Event emitted when request withrawal\n event RequestedWithdrawal(address indexed user, address indexed rewardToken, uint256 indexed pid, uint256 amount);\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChangedV2(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /// @notice An event thats emitted when a delegate account's vote balance changes\n event DelegateVotesChangedV2(address indexed delegate, uint previousBalance, uint newBalance);\n\n /// @notice An event emitted when the reward store address is updated\n event StoreUpdated(address oldXvs, address oldStore, address newXvs, address newStore);\n\n /// @notice An event emitted when the withdrawal locking period is updated for a pool\n event WithdrawalLockingPeriodUpdated(address indexed rewardToken, uint indexed pid, uint oldPeriod, uint newPeriod);\n\n /// @notice An event emitted when the reward amount per block or second is modified for a pool\n event RewardAmountUpdated(address indexed rewardToken, uint oldReward, uint newReward);\n\n /// @notice An event emitted when a new pool is added\n event PoolAdded(\n address indexed rewardToken,\n uint indexed pid,\n address indexed token,\n uint allocPoints,\n uint rewardPerBlockOrSecond,\n uint lockPeriod\n );\n\n /// @notice An event emitted when a pool allocation points are updated\n event PoolUpdated(address indexed rewardToken, uint indexed pid, uint oldAllocPoints, uint newAllocPoints);\n\n /// @notice Event emitted when reward claimed\n event Claim(address indexed user, address indexed rewardToken, uint256 indexed pid, uint256 amount);\n\n /// @notice Event emitted when vault is paused\n event VaultPaused(address indexed admin);\n\n /// @notice Event emitted when vault is resumed after pause\n event VaultResumed(address indexed admin);\n\n /// @notice Event emitted when protocol logs a debt to a user due to insufficient funds for pending reward distribution\n event VaultDebtUpdated(\n address indexed rewardToken,\n address indexed userAddress,\n uint256 oldOwedAmount,\n uint256 newOwedAmount\n );\n\n /// @notice Emitted when prime token contract address is changed\n event NewPrimeToken(\n IPrime indexed oldPrimeToken,\n IPrime indexed newPrimeToken,\n address oldPrimeRewardToken,\n address newPrimeRewardToken,\n uint256 oldPrimePoolId,\n uint256 newPrimePoolId\n );\n\n /**\n * @notice XVSVault constructor\n */\n constructor() public {\n admin = msg.sender;\n }\n\n modifier onlyAdmin() {\n require(msg.sender == admin, \"only admin can\");\n _;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n */\n modifier nonReentrant() {\n require(_notEntered, \"re-entered\");\n _notEntered = false;\n _;\n _notEntered = true; // get a gas-refund post-Istanbul\n }\n\n /**\n * @dev Prevents functions to execute when vault is paused.\n */\n modifier isActive() {\n require(!vaultPaused, \"Vault is paused\");\n _;\n }\n\n /**\n * @notice Pauses vault\n */\n function pause() external {\n _checkAccessAllowed(\"pause()\");\n require(!vaultPaused, \"Vault is already paused\");\n vaultPaused = true;\n emit VaultPaused(msg.sender);\n }\n\n /**\n * @notice Resume vault\n */\n function resume() external {\n _checkAccessAllowed(\"resume()\");\n require(vaultPaused, \"Vault is not paused\");\n vaultPaused = false;\n emit VaultResumed(msg.sender);\n }\n\n /**\n * @notice Returns the number of pools with the specified reward token\n * @param rewardToken Reward token address\n * @return Number of pools that distribute the specified token as a reward\n */\n function poolLength(address rewardToken) external view returns (uint256) {\n return poolInfos[rewardToken].length;\n }\n\n /**\n * @notice Returns the number of reward tokens created per block or second\n * @param _rewardToken Reward token address\n * @return Number of reward tokens created per block or second\n */\n function rewardTokenAmountsPerBlock(address _rewardToken) external view returns (uint256) {\n return rewardTokenAmountsPerBlockOrSecond[_rewardToken];\n }\n\n /**\n * @notice Add a new token pool\n * @dev This vault DOES NOT support deflationary tokens — it expects that\n * the amount of transferred tokens would equal the actually deposited\n * amount. In practice this means that this vault DOES NOT support USDT\n * and similar tokens (that do not provide these guarantees).\n * @param _rewardToken Reward token address\n * @param _allocPoint Number of allocation points assigned to this pool\n * @param _token Staked token\n * @param _rewardPerBlockOrSecond Initial reward per block or second, in terms of _rewardToken\n * @param _lockPeriod A period between withdrawal request and a moment when it's executable\n */\n function add(\n address _rewardToken,\n uint256 _allocPoint,\n IBEP20 _token,\n uint256 _rewardPerBlockOrSecond,\n uint256 _lockPeriod\n ) external {\n _checkAccessAllowed(\"add(address,uint256,address,uint256,uint256)\");\n _ensureNonzeroAddress(_rewardToken);\n _ensureNonzeroAddress(address(_token));\n require(address(xvsStore) != address(0), \"Store contract address is empty\");\n require(_allocPoint > 0, \"Alloc points must not be zero\");\n\n massUpdatePools(_rewardToken);\n\n PoolInfo[] storage poolInfo = poolInfos[_rewardToken];\n\n uint256 length = poolInfo.length;\n for (uint256 pid = 0; pid < length; ++pid) {\n require(poolInfo[pid].token != _token, \"Pool already added\");\n }\n\n // We use balanceOf to get the supply amount, so shouldn't be possible to\n // configure pools with different reward token but the same staked token\n require(!isStakedToken[address(_token)], \"Token exists in other pool\");\n\n totalAllocPoints[_rewardToken] = totalAllocPoints[_rewardToken].add(_allocPoint);\n\n rewardTokenAmountsPerBlockOrSecond[_rewardToken] = _rewardPerBlockOrSecond;\n\n poolInfo.push(\n PoolInfo({\n token: _token,\n allocPoint: _allocPoint,\n lastRewardBlockOrSecond: getBlockNumberOrTimestamp(),\n accRewardPerShare: 0,\n lockPeriod: _lockPeriod\n })\n );\n isStakedToken[address(_token)] = true;\n\n XVSStore(xvsStore).setRewardToken(_rewardToken, true);\n\n emit PoolAdded(\n _rewardToken,\n poolInfo.length - 1,\n address(_token),\n _allocPoint,\n _rewardPerBlockOrSecond,\n _lockPeriod\n );\n }\n\n /**\n * @notice Update the given pool's reward allocation point\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n * @param _allocPoint Number of allocation points assigned to this pool\n */\n function set(address _rewardToken, uint256 _pid, uint256 _allocPoint) external {\n _checkAccessAllowed(\"set(address,uint256,uint256)\");\n _ensureValidPool(_rewardToken, _pid);\n\n massUpdatePools(_rewardToken);\n\n PoolInfo[] storage poolInfo = poolInfos[_rewardToken];\n uint256 newTotalAllocPoints = totalAllocPoints[_rewardToken].sub(poolInfo[_pid].allocPoint).add(_allocPoint);\n require(newTotalAllocPoints > 0, \"Alloc points per reward token must not be zero\");\n\n uint256 oldAllocPoints = poolInfo[_pid].allocPoint;\n poolInfo[_pid].allocPoint = _allocPoint;\n totalAllocPoints[_rewardToken] = newTotalAllocPoints;\n\n emit PoolUpdated(_rewardToken, _pid, oldAllocPoints, _allocPoint);\n }\n\n /**\n * @notice Update the given reward token's amount per block or second\n * @param _rewardToken Reward token address\n * @param _rewardAmount Number of allocation points assigned to this pool\n */\n function setRewardAmountPerBlockOrSecond(address _rewardToken, uint256 _rewardAmount) external {\n _checkAccessAllowed(\"setRewardAmountPerBlockOrSecond(address,uint256)\");\n require(XVSStore(xvsStore).rewardTokens(_rewardToken), \"Invalid reward token\");\n massUpdatePools(_rewardToken);\n uint256 oldReward = rewardTokenAmountsPerBlockOrSecond[_rewardToken];\n rewardTokenAmountsPerBlockOrSecond[_rewardToken] = _rewardAmount;\n\n emit RewardAmountUpdated(_rewardToken, oldReward, _rewardAmount);\n }\n\n /**\n * @notice Update the lock period after which a requested withdrawal can be executed\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n * @param _newPeriod New lock period\n */\n function setWithdrawalLockingPeriod(address _rewardToken, uint256 _pid, uint256 _newPeriod) external {\n _checkAccessAllowed(\"setWithdrawalLockingPeriod(address,uint256,uint256)\");\n _ensureValidPool(_rewardToken, _pid);\n require(_newPeriod > 0 && _newPeriod < MAX_LOCK_PERIOD, \"Invalid new locking period\");\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n uint256 oldPeriod = pool.lockPeriod;\n pool.lockPeriod = _newPeriod;\n\n emit WithdrawalLockingPeriodUpdated(_rewardToken, _pid, oldPeriod, _newPeriod);\n }\n\n /**\n * @notice Deposit XVSVault for XVS allocation\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _amount The amount to deposit to vault\n */\n function deposit(address _rewardToken, uint256 _pid, uint256 _amount) external nonReentrant isActive {\n _ensureValidPool(_rewardToken, _pid);\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n UserInfo storage user = userInfos[_rewardToken][_pid][msg.sender];\n _updatePool(_rewardToken, _pid);\n require(pendingWithdrawalsBeforeUpgrade(_rewardToken, _pid, msg.sender) == 0, \"execute pending withdrawal\");\n\n if (user.amount > 0) {\n uint256 pending = _computeReward(user, pool);\n if (pending > 0) {\n _transferReward(_rewardToken, msg.sender, pending);\n emit Claim(msg.sender, _rewardToken, _pid, pending);\n }\n }\n pool.token.safeTransferFrom(msg.sender, address(this), _amount);\n user.amount = user.amount.add(_amount);\n user.rewardDebt = _cumulativeReward(user, pool);\n\n // Update Delegate Amount\n if (address(pool.token) == xvsAddress) {\n _moveDelegates(address(0), delegates[msg.sender], safe96(_amount, \"XVSVault::deposit: votes overflow\"));\n }\n\n if (primeRewardToken == _rewardToken && _pid == primePoolId) {\n primeToken.xvsUpdated(msg.sender);\n }\n\n emit Deposit(msg.sender, _rewardToken, _pid, _amount);\n }\n\n /**\n * @notice Claim rewards for pool\n * @param _account The account for which to claim rewards\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n */\n function claim(address _account, address _rewardToken, uint256 _pid) external nonReentrant isActive {\n _ensureValidPool(_rewardToken, _pid);\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n UserInfo storage user = userInfos[_rewardToken][_pid][_account];\n _updatePool(_rewardToken, _pid);\n require(pendingWithdrawalsBeforeUpgrade(_rewardToken, _pid, _account) == 0, \"execute pending withdrawal\");\n\n if (user.amount > 0) {\n uint256 pending = _computeReward(user, pool);\n\n if (pending > 0) {\n user.rewardDebt = _cumulativeReward(user, pool);\n\n _transferReward(_rewardToken, _account, pending);\n emit Claim(_account, _rewardToken, _pid, pending);\n }\n }\n }\n\n /**\n * @notice Pushes withdrawal request to the requests array and updates\n * the pending withdrawals amount. The requests are always sorted\n * by unlock time (descending) so that the earliest to execute requests\n * are always at the end of the array.\n * @param _user The user struct storage pointer\n * @param _requests The user's requests array storage pointer\n * @param _amount The amount being requested\n */\n function pushWithdrawalRequest(\n UserInfo storage _user,\n WithdrawalRequest[] storage _requests,\n uint _amount,\n uint _lockedUntil\n ) internal {\n uint i = _requests.length;\n _requests.push(WithdrawalRequest(0, 0, 1));\n // Keep it sorted so that the first to get unlocked request is always at the end\n for (; i > 0 && _requests[i - 1].lockedUntil <= _lockedUntil; --i) {\n _requests[i] = _requests[i - 1];\n }\n _requests[i] = WithdrawalRequest(_amount, _lockedUntil.toUint128(), 1);\n _user.pendingWithdrawals = _user.pendingWithdrawals.add(_amount);\n }\n\n /**\n * @notice Pops the requests with unlock time < now from the requests\n * array and deducts the computed amount from the user's pending\n * withdrawals counter. Assumes that the requests array is sorted\n * by unclock time (descending).\n * @dev This function **removes** the eligible requests from the requests\n * array. If this function is called, the withdrawal should actually\n * happen (or the transaction should be reverted).\n * @param _user The user struct storage pointer\n * @param _requests The user's requests array storage pointer\n * @return beforeUpgradeWithdrawalAmount The amount eligible for withdrawal before upgrade (this amount should be\n * sent to the user, otherwise the state would be inconsistent).\n * @return afterUpgradeWithdrawalAmount The amount eligible for withdrawal after upgrade (this amount should be\n * sent to the user, otherwise the state would be inconsistent).\n */\n function popEligibleWithdrawalRequests(\n UserInfo storage _user,\n WithdrawalRequest[] storage _requests\n ) internal returns (uint beforeUpgradeWithdrawalAmount, uint afterUpgradeWithdrawalAmount) {\n // Since the requests are sorted by their unlock time, we can just\n // pop them from the array and stop at the first not-yet-eligible one\n for (uint i = _requests.length; i > 0 && isUnlocked(_requests[i - 1]); --i) {\n if (_requests[i - 1].afterUpgrade == 1) {\n afterUpgradeWithdrawalAmount = afterUpgradeWithdrawalAmount.add(_requests[i - 1].amount);\n } else {\n beforeUpgradeWithdrawalAmount = beforeUpgradeWithdrawalAmount.add(_requests[i - 1].amount);\n }\n\n _requests.pop();\n }\n _user.pendingWithdrawals = _user.pendingWithdrawals.sub(\n afterUpgradeWithdrawalAmount.add(beforeUpgradeWithdrawalAmount)\n );\n return (beforeUpgradeWithdrawalAmount, afterUpgradeWithdrawalAmount);\n }\n\n /**\n * @notice Checks if the request is eligible for withdrawal.\n * @param _request The request struct storage pointer\n * @return True if the request is eligible for withdrawal, false otherwise\n */\n function isUnlocked(WithdrawalRequest storage _request) private view returns (bool) {\n return _request.lockedUntil <= block.timestamp;\n }\n\n /**\n * @notice Execute withdrawal to XVSVault for XVS allocation\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n */\n function executeWithdrawal(address _rewardToken, uint256 _pid) external nonReentrant isActive {\n _ensureValidPool(_rewardToken, _pid);\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n UserInfo storage user = userInfos[_rewardToken][_pid][msg.sender];\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][msg.sender];\n\n uint256 beforeUpgradeWithdrawalAmount;\n uint256 afterUpgradeWithdrawalAmount;\n\n (beforeUpgradeWithdrawalAmount, afterUpgradeWithdrawalAmount) = popEligibleWithdrawalRequests(user, requests);\n require(beforeUpgradeWithdrawalAmount > 0 || afterUpgradeWithdrawalAmount > 0, \"nothing to withdraw\");\n\n // Having both old-style and new-style requests is not allowed and shouldn't be possible\n require(beforeUpgradeWithdrawalAmount == 0 || afterUpgradeWithdrawalAmount == 0, \"inconsistent state\");\n\n if (beforeUpgradeWithdrawalAmount > 0) {\n _updatePool(_rewardToken, _pid);\n uint256 pending = user.amount.mul(pool.accRewardPerShare).div(1e12).sub(user.rewardDebt);\n XVSStore(xvsStore).safeRewardTransfer(_rewardToken, msg.sender, pending);\n user.amount = user.amount.sub(beforeUpgradeWithdrawalAmount);\n user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(1e12);\n pool.token.safeTransfer(address(msg.sender), beforeUpgradeWithdrawalAmount);\n } else {\n user.amount = user.amount.sub(afterUpgradeWithdrawalAmount);\n totalPendingWithdrawals[_rewardToken][_pid] = totalPendingWithdrawals[_rewardToken][_pid].sub(\n afterUpgradeWithdrawalAmount\n );\n pool.token.safeTransfer(address(msg.sender), afterUpgradeWithdrawalAmount);\n }\n\n emit ExecutedWithdrawal(\n msg.sender,\n _rewardToken,\n _pid,\n beforeUpgradeWithdrawalAmount.add(afterUpgradeWithdrawalAmount)\n );\n }\n\n /**\n * @notice Returns before and after upgrade pending withdrawal amount\n * @param _requests The user's requests array storage pointer\n * @return beforeUpgradeWithdrawalAmount The amount eligible for withdrawal before upgrade\n * @return afterUpgradeWithdrawalAmount The amount eligible for withdrawal after upgrade\n */\n function getRequestedWithdrawalAmount(\n WithdrawalRequest[] storage _requests\n ) internal view returns (uint beforeUpgradeWithdrawalAmount, uint afterUpgradeWithdrawalAmount) {\n for (uint i = _requests.length; i > 0; --i) {\n if (_requests[i - 1].afterUpgrade == 1) {\n afterUpgradeWithdrawalAmount = afterUpgradeWithdrawalAmount.add(_requests[i - 1].amount);\n } else {\n beforeUpgradeWithdrawalAmount = beforeUpgradeWithdrawalAmount.add(_requests[i - 1].amount);\n }\n }\n return (beforeUpgradeWithdrawalAmount, afterUpgradeWithdrawalAmount);\n }\n\n /**\n * @notice Request withdrawal to XVSVault for XVS allocation\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _amount The amount to withdraw from the vault\n */\n function requestWithdrawal(address _rewardToken, uint256 _pid, uint256 _amount) external nonReentrant isActive {\n _ensureValidPool(_rewardToken, _pid);\n require(_amount > 0, \"requested amount cannot be zero\");\n UserInfo storage user = userInfos[_rewardToken][_pid][msg.sender];\n require(user.amount >= user.pendingWithdrawals.add(_amount), \"requested amount is invalid\");\n\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][msg.sender];\n\n uint beforeUpgradeWithdrawalAmount;\n\n (beforeUpgradeWithdrawalAmount, ) = getRequestedWithdrawalAmount(requests);\n require(beforeUpgradeWithdrawalAmount == 0, \"execute pending withdrawal\");\n\n _updatePool(_rewardToken, _pid);\n uint256 pending = _computeReward(user, pool);\n _transferReward(_rewardToken, msg.sender, pending);\n\n uint lockedUntil = pool.lockPeriod.add(block.timestamp);\n\n pushWithdrawalRequest(user, requests, _amount, lockedUntil);\n totalPendingWithdrawals[_rewardToken][_pid] = totalPendingWithdrawals[_rewardToken][_pid].add(_amount);\n user.rewardDebt = _cumulativeReward(user, pool);\n\n // Update Delegate Amount\n if (address(pool.token) == xvsAddress) {\n _moveDelegates(\n delegates[msg.sender],\n address(0),\n safe96(_amount, \"XVSVault::requestWithdrawal: votes overflow\")\n );\n }\n\n if (primeRewardToken == _rewardToken && _pid == primePoolId) {\n primeToken.xvsUpdated(msg.sender);\n }\n\n emit Claim(msg.sender, _rewardToken, _pid, pending);\n emit RequestedWithdrawal(msg.sender, _rewardToken, _pid, _amount);\n }\n\n /**\n * @notice Get unlocked withdrawal amount\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _user The User Address\n * @return withdrawalAmount Amount that the user can withdraw\n */\n function getEligibleWithdrawalAmount(\n address _rewardToken,\n uint256 _pid,\n address _user\n ) external view returns (uint withdrawalAmount) {\n _ensureValidPool(_rewardToken, _pid);\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][_user];\n // Since the requests are sorted by their unlock time, we can take\n // the entries from the end of the array and stop at the first\n // not-yet-eligible one\n for (uint i = requests.length; i > 0 && isUnlocked(requests[i - 1]); --i) {\n withdrawalAmount = withdrawalAmount.add(requests[i - 1].amount);\n }\n return withdrawalAmount;\n }\n\n /**\n * @notice Get requested amount\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _user The User Address\n * @return Total amount of requested but not yet executed withdrawals (including both executable and locked ones)\n */\n function getRequestedAmount(address _rewardToken, uint256 _pid, address _user) external view returns (uint256) {\n _ensureValidPool(_rewardToken, _pid);\n UserInfo storage user = userInfos[_rewardToken][_pid][_user];\n return user.pendingWithdrawals;\n }\n\n /**\n * @notice Returns the array of withdrawal requests that have not been executed yet\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _user The User Address\n * @return An array of withdrawal requests\n */\n function getWithdrawalRequests(\n address _rewardToken,\n uint256 _pid,\n address _user\n ) external view returns (WithdrawalRequest[] memory) {\n _ensureValidPool(_rewardToken, _pid);\n return withdrawalRequests[_rewardToken][_pid][_user];\n }\n\n /**\n * @notice View function to see pending XVSs on frontend\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n * @param _user User address\n * @return Reward the user is eligible for in this pool, in terms of _rewardToken\n */\n function pendingReward(address _rewardToken, uint256 _pid, address _user) external view returns (uint256) {\n _ensureValidPool(_rewardToken, _pid);\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n UserInfo storage user = userInfos[_rewardToken][_pid][_user];\n uint256 accRewardPerShare = pool.accRewardPerShare;\n uint256 supply = pool.token.balanceOf(address(this)).sub(totalPendingWithdrawals[_rewardToken][_pid]);\n uint256 curBlockNumberOrSecond = getBlockNumberOrTimestamp();\n uint256 rewardTokenPerBlockOrSecond = rewardTokenAmountsPerBlockOrSecond[_rewardToken];\n if (curBlockNumberOrSecond > pool.lastRewardBlockOrSecond && supply != 0) {\n uint256 multiplier = curBlockNumberOrSecond.sub(pool.lastRewardBlockOrSecond);\n uint256 reward = multiplier.mul(rewardTokenPerBlockOrSecond).mul(pool.allocPoint).div(\n totalAllocPoints[_rewardToken]\n );\n accRewardPerShare = accRewardPerShare.add(reward.mul(1e12).div(supply));\n }\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][_user];\n (, uint256 afterUpgradeWithdrawalAmount) = getRequestedWithdrawalAmount(requests);\n return user.amount.sub(afterUpgradeWithdrawalAmount).mul(accRewardPerShare).div(1e12).sub(user.rewardDebt);\n }\n\n // Update reward variables for all pools. Be careful of gas spending!\n function massUpdatePools(address _rewardToken) internal {\n uint256 length = poolInfos[_rewardToken].length;\n for (uint256 pid = 0; pid < length; ++pid) {\n _updatePool(_rewardToken, pid);\n }\n }\n\n /**\n * @notice Update reward variables of the given pool to be up-to-date\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n */\n function updatePool(address _rewardToken, uint256 _pid) external isActive {\n _ensureValidPool(_rewardToken, _pid);\n _updatePool(_rewardToken, _pid);\n }\n\n // Update reward variables of the given pool to be up-to-date.\n function _updatePool(address _rewardToken, uint256 _pid) internal {\n PoolInfo storage pool = poolInfos[_rewardToken][_pid];\n if (getBlockNumberOrTimestamp() <= pool.lastRewardBlockOrSecond) {\n return;\n }\n uint256 supply = pool.token.balanceOf(address(this));\n supply = supply.sub(totalPendingWithdrawals[_rewardToken][_pid]);\n if (supply == 0) {\n pool.lastRewardBlockOrSecond = getBlockNumberOrTimestamp();\n return;\n }\n uint256 curBlockNumberOrSecond = getBlockNumberOrTimestamp();\n uint256 multiplier = curBlockNumberOrSecond.sub(pool.lastRewardBlockOrSecond);\n uint256 reward = multiplier.mul(rewardTokenAmountsPerBlockOrSecond[_rewardToken]).mul(pool.allocPoint).div(\n totalAllocPoints[_rewardToken]\n );\n pool.accRewardPerShare = pool.accRewardPerShare.add(reward.mul(1e12).div(supply));\n pool.lastRewardBlockOrSecond = getBlockNumberOrTimestamp();\n }\n\n function _ensureValidPool(address rewardToken, uint256 pid) internal view {\n require(pid < poolInfos[rewardToken].length, \"vault: pool exists?\");\n }\n\n /**\n * @notice Get user info with reward token address and pid\n * @param _rewardToken Reward token address\n * @param _pid Pool index\n * @param _user User address\n * @return amount Deposited amount\n * @return rewardDebt Reward debt (technical value used to track past payouts)\n * @return pendingWithdrawals Requested but not yet executed withdrawals\n */\n function getUserInfo(\n address _rewardToken,\n uint256 _pid,\n address _user\n ) external view returns (uint256 amount, uint256 rewardDebt, uint256 pendingWithdrawals) {\n _ensureValidPool(_rewardToken, _pid);\n UserInfo storage user = userInfos[_rewardToken][_pid][_user];\n amount = user.amount;\n rewardDebt = user.rewardDebt;\n pendingWithdrawals = user.pendingWithdrawals;\n }\n\n /**\n * @notice Gets the total pending withdrawal amount of a user before upgrade\n * @param _rewardToken The Reward Token Address\n * @param _pid The Pool Index\n * @param _user The address of the user\n * @return beforeUpgradeWithdrawalAmount Total pending withdrawal amount in requests made before the vault upgrade\n */\n function pendingWithdrawalsBeforeUpgrade(\n address _rewardToken,\n uint256 _pid,\n address _user\n ) public view returns (uint256 beforeUpgradeWithdrawalAmount) {\n WithdrawalRequest[] storage requests = withdrawalRequests[_rewardToken][_pid][_user];\n (beforeUpgradeWithdrawalAmount, ) = getRequestedWithdrawalAmount(requests);\n return beforeUpgradeWithdrawalAmount;\n }\n\n /**\n * @notice Get the XVS stake balance of an account (excluding the pending withdrawals)\n * @param account The address of the account to check\n * @return The balance that user staked\n */\n function getStakeAmount(address account) internal view returns (uint96) {\n require(xvsAddress != address(0), \"XVSVault::getStakeAmount: xvs address is not set\");\n\n PoolInfo[] storage poolInfo = poolInfos[xvsAddress];\n\n uint256 length = poolInfo.length;\n for (uint256 pid = 0; pid < length; ++pid) {\n if (address(poolInfo[pid].token) == address(xvsAddress)) {\n UserInfo storage user = userInfos[xvsAddress][pid][account];\n return safe96(user.amount.sub(user.pendingWithdrawals), \"XVSVault::getStakeAmount: votes overflow\");\n }\n }\n return uint96(0);\n }\n\n /**\n * @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The address to delegate votes to\n */\n function delegate(address delegatee) external isActive {\n return _delegate(msg.sender, delegatee);\n }\n\n /**\n * @notice Delegates votes from signatory to `delegatee`\n * @param delegatee The address to delegate votes to\n * @param nonce The contract state required to match the signature\n * @param expiry The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n function delegateBySig(\n address delegatee,\n uint nonce,\n uint expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external isActive {\n bytes32 domainSeparator = keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(\"XVSVault\")), getChainId(), address(this))\n );\n bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ECDSA.recover(digest, v, r, s);\n require(nonce == nonces[signatory]++, \"XVSVault::delegateBySig: invalid nonce\");\n require(block.timestamp <= expiry, \"XVSVault::delegateBySig: signature expired\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Gets the current votes balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for `account`\n */\n function getCurrentVotes(address account) external view returns (uint96) {\n uint32 nCheckpoints = numCheckpoints[account];\n return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n function _delegate(address delegator, address delegatee) internal {\n address currentDelegate = delegates[delegator];\n uint96 delegatorBalance = getStakeAmount(delegator);\n delegates[delegator] = delegatee;\n\n emit DelegateChangedV2(delegator, currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {\n if (srcRep != dstRep && amount > 0) {\n if (srcRep != address(0)) {\n uint32 srcRepNum = numCheckpoints[srcRep];\n uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n uint96 srcRepNew = sub96(srcRepOld, amount, \"XVSVault::_moveVotes: vote amount underflows\");\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint96 dstRepNew = add96(dstRepOld, amount, \"XVSVault::_moveVotes: vote amount overflows\");\n _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {\n uint32 blockNumberOrSecond = safe32(\n getBlockNumberOrTimestamp(),\n \"XVSVault::_writeCheckpoint: block number or second exceeds 32 bits\"\n );\n\n if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlockOrSecond == blockNumberOrSecond) {\n checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n } else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumberOrSecond, newVotes);\n numCheckpoints[delegatee] = nCheckpoints + 1;\n }\n\n emit DelegateVotesChangedV2(delegatee, oldVotes, newVotes);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n < 2 ** 32, errorMessage);\n return uint32(n);\n }\n\n function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {\n require(n < 2 ** 96, errorMessage);\n return uint96(n);\n }\n\n function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n uint96 c = a + b;\n require(c >= a, errorMessage);\n return c;\n }\n\n function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n function getChainId() internal pure returns (uint) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n return chainId;\n }\n\n /**\n * @notice Determine the xvs stake balance for an account\n * @param account The address of the account to check\n * @param blockNumberOrSecond The block number or second to get the vote balance at\n * @return The balance that user staked\n */\n function getPriorVotes(address account, uint256 blockNumberOrSecond) external view returns (uint96) {\n require(blockNumberOrSecond < getBlockNumberOrTimestamp(), \"XVSVault::getPriorVotes: not yet determined\");\n\n uint32 nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n }\n\n // First check most recent balance\n if (checkpoints[account][nCheckpoints - 1].fromBlockOrSecond <= blockNumberOrSecond) {\n return checkpoints[account][nCheckpoints - 1].votes;\n }\n\n // Next check implicit zero balance\n if (checkpoints[account][0].fromBlockOrSecond > blockNumberOrSecond) {\n return 0;\n }\n\n uint32 lower = 0;\n uint32 upper = nCheckpoints - 1;\n while (upper > lower) {\n uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n Checkpoint memory cp = checkpoints[account][center];\n if (cp.fromBlockOrSecond == blockNumberOrSecond) {\n return cp.votes;\n } else if (cp.fromBlockOrSecond < blockNumberOrSecond) {\n lower = center;\n } else {\n upper = center - 1;\n }\n }\n return checkpoints[account][lower].votes;\n }\n\n /*** Admin Functions ***/\n\n function _become(XVSVaultProxy xvsVaultProxy) external {\n require(msg.sender == xvsVaultProxy.admin(), \"only proxy admin can change brains\");\n require(xvsVaultProxy._acceptImplementation() == 0, \"change not authorized\");\n }\n\n function setXvsStore(address _xvs, address _xvsStore) external onlyAdmin {\n _ensureNonzeroAddress(_xvs);\n _ensureNonzeroAddress(_xvsStore);\n\n address oldXvsContract = xvsAddress;\n address oldStore = xvsStore;\n require(oldXvsContract == address(0), \"already initialized\");\n\n xvsAddress = _xvs;\n xvsStore = _xvsStore;\n\n _notEntered = true;\n\n emit StoreUpdated(oldXvsContract, oldStore, _xvs, _xvsStore);\n }\n\n /**\n * @notice Sets the address of the prime token contract\n * @param _primeToken address of the prime token contract\n * @param _primeRewardToken address of reward token\n * @param _primePoolId pool id for reward\n */\n function setPrimeToken(IPrime _primeToken, address _primeRewardToken, uint256 _primePoolId) external onlyAdmin {\n require(address(_primeToken) != address(0), \"prime token cannot be zero address\");\n require(_primeRewardToken != address(0), \"reward cannot be zero address\");\n\n _ensureValidPool(_primeRewardToken, _primePoolId);\n\n emit NewPrimeToken(primeToken, _primeToken, primeRewardToken, _primeRewardToken, primePoolId, _primePoolId);\n\n primeToken = _primeToken;\n primeRewardToken = _primeRewardToken;\n primePoolId = _primePoolId;\n }\n\n /**\n * @dev Initializes the contract to use either blocks or seconds\n * @param timeBased_ A boolean indicating whether the contract is based on time or block\n * If timeBased is true than blocksPerYear_ param is ignored as blocksOrSecondsPerYear is set to SECONDS_PER_YEAR\n * @param blocksPerYear_ The number of blocks per year\n */\n function initializeTimeManager(bool timeBased_, uint256 blocksPerYear_) external onlyAdmin {\n _initializeTimeManager(timeBased_, blocksPerYear_);\n }\n\n /**\n * @notice Sets the address of the access control of this contract\n * @dev Admin function to set the access control address\n * @param newAccessControlAddress New address for the access control\n */\n function setAccessControl(address newAccessControlAddress) external onlyAdmin {\n _setAccessControlManager(newAccessControlAddress);\n }\n\n /**\n * @dev Reverts if the provided address is a zero address\n * @param address_ Address to check\n */\n function _ensureNonzeroAddress(address address_) internal pure {\n require(address_ != address(0), \"zero address not allowed\");\n }\n\n /**\n * @dev Transfers the reward to the user, taking into account the rewards store\n * balance and the previous debt. If there are not enough rewards in the store,\n * transfers the available funds and records the debt amount in pendingRewardTransfers.\n * @param rewardToken Reward token address\n * @param userAddress User address\n * @param amount Reward amount, in reward tokens\n */\n function _transferReward(address rewardToken, address userAddress, uint256 amount) internal {\n address xvsStore_ = xvsStore;\n uint256 storeBalance = IBEP20(rewardToken).balanceOf(xvsStore_);\n uint256 debtDueToFailedTransfers = pendingRewardTransfers[rewardToken][userAddress];\n uint256 fullAmount = amount.add(debtDueToFailedTransfers);\n\n if (fullAmount <= storeBalance) {\n if (debtDueToFailedTransfers != 0) {\n pendingRewardTransfers[rewardToken][userAddress] = 0;\n emit VaultDebtUpdated(rewardToken, userAddress, debtDueToFailedTransfers, 0);\n }\n XVSStore(xvsStore_).safeRewardTransfer(rewardToken, userAddress, fullAmount);\n return;\n }\n // Overflow isn't possible due to the check above\n uint256 newOwedAmount = fullAmount - storeBalance;\n pendingRewardTransfers[rewardToken][userAddress] = newOwedAmount;\n emit VaultDebtUpdated(rewardToken, userAddress, debtDueToFailedTransfers, newOwedAmount);\n XVSStore(xvsStore_).safeRewardTransfer(rewardToken, userAddress, storeBalance);\n }\n\n /**\n * @dev Computes cumulative reward for all user's shares\n * @param user UserInfo storage struct\n * @param pool PoolInfo storage struct\n */\n function _cumulativeReward(UserInfo storage user, PoolInfo storage pool) internal view returns (uint256) {\n return user.amount.sub(user.pendingWithdrawals).mul(pool.accRewardPerShare).div(1e12);\n }\n\n /**\n * @dev Computes the reward for all user's shares\n * @param user UserInfo storage struct\n * @param pool PoolInfo storage struct\n */\n function _computeReward(UserInfo storage user, PoolInfo storage pool) internal view returns (uint256) {\n return _cumulativeReward(user, pool).sub(user.rewardDebt);\n }\n}\n" + }, + "contracts/XVSVault/XVSVaultErrorReporter.sol": { + "content": "pragma solidity ^0.5.16;\n\ncontract XVSVaultErrorReporter {\n enum Error {\n NO_ERROR,\n UNAUTHORIZED\n }\n\n enum FailureInfo {\n ACCEPT_ADMIN_PENDING_ADMIN_CHECK,\n ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK,\n SET_PENDING_ADMIN_OWNER_CHECK,\n SET_PENDING_IMPLEMENTATION_OWNER_CHECK\n }\n\n /**\n * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary\n * contract-specific code that enables us to report opaque error codes from upgradeable contracts.\n **/\n event Failure(uint error, uint info, uint detail);\n\n /**\n * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator\n */\n function fail(Error err, FailureInfo info) internal returns (uint) {\n emit Failure(uint(err), uint(info), 0);\n\n return uint(err);\n }\n\n /**\n * @dev use this when reporting an opaque error from an upgradeable collaborator contract\n */\n function failOpaque(Error err, FailureInfo info, uint opaqueError) internal returns (uint) {\n emit Failure(uint(err), uint(info), opaqueError);\n\n return uint(err);\n }\n}\n" + }, + "contracts/XVSVault/XVSVaultProxy.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"./XVSVaultStorage.sol\";\nimport \"./XVSVaultErrorReporter.sol\";\n\n/**\n * @title XVS Vault Proxy\n * @author Venus\n * @notice XVS Vault Proxy contract\n */\ncontract XVSVaultProxy is XVSVaultAdminStorage, XVSVaultErrorReporter {\n /**\n * @notice Emitted when pendingXVSVaultImplementation is changed\n */\n event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation);\n\n /**\n * @notice Emitted when pendingXVSVaultImplementation is accepted, which means XVS Vault implementation is updated\n */\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /**\n * @notice Emitted when pendingAdmin is changed\n */\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /**\n * @notice Emitted when pendingAdmin is accepted, which means admin is updated\n */\n event NewAdmin(address oldAdmin, address newAdmin);\n\n constructor() public {\n // Set admin to caller\n admin = msg.sender;\n }\n\n /*** Admin Functions ***/\n function _setPendingImplementation(address newPendingImplementation) public returns (uint) {\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_IMPLEMENTATION_OWNER_CHECK);\n }\n\n address oldPendingImplementation = pendingXVSVaultImplementation;\n\n pendingXVSVaultImplementation = newPendingImplementation;\n\n emit NewPendingImplementation(oldPendingImplementation, pendingXVSVaultImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts new implementation of XVS Vault. msg.sender must be pendingImplementation\n * @dev Admin function for new implementation to accept it's role as implementation\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptImplementation() public returns (uint) {\n // Check caller is pendingImplementation\n if (msg.sender != pendingXVSVaultImplementation) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldImplementation = implementation;\n address oldPendingImplementation = pendingXVSVaultImplementation;\n\n implementation = pendingXVSVaultImplementation;\n\n pendingXVSVaultImplementation = address(0);\n\n emit NewImplementation(oldImplementation, implementation);\n emit NewPendingImplementation(oldPendingImplementation, pendingXVSVaultImplementation);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _setPendingAdmin(address newPendingAdmin) public returns (uint) {\n // Check caller = admin\n if (msg.sender != admin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.SET_PENDING_ADMIN_OWNER_CHECK);\n }\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)\n */\n function _acceptAdmin() public returns (uint) {\n // Check caller is pendingAdmin\n if (msg.sender != pendingAdmin) {\n return fail(Error.UNAUTHORIZED, FailureInfo.ACCEPT_ADMIN_PENDING_ADMIN_CHECK);\n }\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n\n return uint(Error.NO_ERROR);\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns\n * or forwards reverts.\n */\n function() external payable {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize)\n\n switch success\n case 0 {\n revert(free_mem_ptr, returndatasize)\n }\n default {\n return(free_mem_ptr, returndatasize)\n }\n }\n }\n}\n" + }, + "contracts/XVSVault/XVSVaultStorage.sol": { + "content": "pragma solidity ^0.5.16;\n\nimport \"../Utils/SafeMath.sol\";\nimport \"../Utils/IBEP20.sol\";\nimport \"../Tokens/Prime/IPrime.sol\";\n\ncontract XVSVaultAdminStorage {\n /**\n * @notice Administrator for this contract\n */\n address public admin;\n\n /**\n * @notice Pending administrator for this contract\n */\n address public pendingAdmin;\n\n /**\n * @notice Active brains of XVS Vault\n */\n address public implementation;\n\n /**\n * @notice Pending brains of XVS Vault\n */\n address public pendingXVSVaultImplementation;\n}\n\ncontract XVSVaultStorageV1 is XVSVaultAdminStorage {\n /// @notice Guard variable for re-entrancy checks\n bool internal _notEntered;\n\n /// @notice The reward token store\n address public xvsStore;\n\n /// @notice The xvs token address\n address public xvsAddress;\n\n // Reward tokens created per block or second indentified by reward token address.\n mapping(address => uint256) public rewardTokenAmountsPerBlockOrSecond;\n\n /// @notice Info of each user.\n struct UserInfo {\n uint256 amount;\n uint256 rewardDebt;\n uint256 pendingWithdrawals;\n }\n\n // Info of each pool.\n struct PoolInfo {\n IBEP20 token; // Address of token contract to stake.\n uint256 allocPoint; // How many allocation points assigned to this pool.\n uint256 lastRewardBlockOrSecond; // Last block number or second that reward tokens distribution occurs.\n uint256 accRewardPerShare; // Accumulated per share, times 1e12. See below.\n uint256 lockPeriod; // Min time between withdrawal request and its execution.\n }\n\n // Infomation about a withdrawal request\n struct WithdrawalRequest {\n uint256 amount;\n uint128 lockedUntil;\n uint128 afterUpgrade;\n }\n\n // Info of each user that stakes tokens.\n mapping(address => mapping(uint256 => mapping(address => UserInfo))) internal userInfos;\n\n // Info of each pool.\n mapping(address => PoolInfo[]) public poolInfos;\n\n // Total allocation points. Must be the sum of all allocation points in all pools.\n mapping(address => uint256) public totalAllocPoints;\n\n // Info of requested but not yet executed withdrawals\n mapping(address => mapping(uint256 => mapping(address => WithdrawalRequest[]))) internal withdrawalRequests;\n\n /// @notice DEPRECATED A record of each accounts delegate (before the voting power fix)\n mapping(address => address) private __oldDelegatesSlot;\n\n /// @notice A checkpoint for marking number of votes from a given block or second\n struct Checkpoint {\n uint32 fromBlockOrSecond;\n uint96 votes;\n }\n\n /// @notice DEPRECATED A record of votes checkpoints for each account, by index (before the voting power fix)\n mapping(address => mapping(uint32 => Checkpoint)) private __oldCheckpointsSlot;\n\n /// @notice DEPRECATED The number of checkpoints for each account (before the voting power fix)\n mapping(address => uint32) private __oldNumCheckpointsSlot;\n\n /// @notice A record of states for signing / validating signatures\n mapping(address => uint) public nonces;\n\n /// @notice The EIP-712 typehash for the contract's domain\n bytes32 public constant DOMAIN_TYPEHASH =\n keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation struct used by the contract\n bytes32 public constant DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n}\n\ncontract XVSVaultStorage is XVSVaultStorageV1 {\n /// @notice A record of each accounts delegate\n mapping(address => address) public delegates;\n\n /// @notice A record of votes checkpoints for each account, by index\n mapping(address => mapping(uint32 => Checkpoint)) public checkpoints;\n\n /// @notice The number of checkpoints for each account\n mapping(address => uint32) public numCheckpoints;\n\n /// @notice Tracks pending withdrawals for all users for a particular reward token and pool id\n mapping(address => mapping(uint256 => uint256)) internal totalPendingWithdrawals;\n\n /// @notice pause indicator for Vault\n bool public vaultPaused;\n\n /// @notice if the token is added to any of the pools\n mapping(address => bool) public isStakedToken;\n\n /// @notice Amount we owe to users because of failed transfer attempts\n mapping(address => mapping(address => uint256)) public pendingRewardTransfers;\n\n /// @notice Prime token contract address\n IPrime public primeToken;\n\n /// @notice Reward token for which prime token is issued for staking\n address public primeRewardToken;\n\n /// @notice Pool ID for which prime token is issued for staking\n uint256 public primePoolId;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/bsctestnet_addresses.json b/deployments/bsctestnet_addresses.json index ba807c77c..2d57e175d 100644 --- a/deployments/bsctestnet_addresses.json +++ b/deployments/bsctestnet_addresses.json @@ -13,12 +13,12 @@ "Liquidator": "0x55AEABa76ecf144031Ef64E222166eb28Cb4865F", "Liquidator_Implementation": "0x83372155dd4a4306af82795d5a27d40188ed1f3b", "Liquidator_Proxy": "0x55AEABa76ecf144031Ef64E222166eb28Cb4865F", - "MarketFacet": "0xF2F2aE5480c4527787Fb7Cde1Ed9A3EdfD40A60d", + "MarketFacet": "0x00a949FfDa9B216fBA9C4E5b40ef561Af0FDb723", "MockFDUSD": "0xcF27439fA231af9931ee40c4f27Bb77B83826F3C", "PegStability_USDT": "0xB21E69eef4Bc1D64903fa28D9b32491B1c0786F1", "PegStability_USDT_Implementation": "0xDDa903294fB71141302aD3Bf2AF37dD6Cbd5DBbF", "PegStability_USDT_Proxy": "0xB21E69eef4Bc1D64903fa28D9b32491B1c0786F1", - "PolicyFacet": "0x7b17b28687B817158c20e3d1bf100106fBE794cf", + "PolicyFacet": "0x085C8d0133291348004AabFfbE7CAc2097aF2aa1", "Prime": "0xe840F8EC2Dc50E7D22e5e2991975b9F6e34b62Ad", "PrimeLiquidityProvider": "0xAdeddc73eAFCbed174e6C400165b111b0cb80B7E", "PrimeLiquidityProviderTest": "0x7a780FbBa026568025a82101De65863A94CcD8f7", @@ -30,7 +30,7 @@ "Prime_Proxy": "0xe840F8EC2Dc50E7D22e5e2991975b9F6e34b62Ad", "RewardFacet": "0x905006DCD5DbAa9B67359bcB341a0C49AfC8d0A6", "SXP": "0x75107940Cf1121232C0559c747A986DEfbc69DA9", - "SetterFacet": "0xaBdE9599a4aEcE4fEC59fBF2b8445149bc8B2c70", + "SetterFacet": "0x490DFD07f592452307817C4283866035BDb3b275", "SnapshotLens": "0x61610DeC84448Ed17A2a0317667a99ca0CC6f697", "SwapRouterCorePool": "0x83edf1deE1B730b7e8e13C00ba76027D63a51ac0", "SwapRouterDefi": "0x76B88ff4579B35D2722B7383b9B9ce831dc89B72", diff --git a/tests/hardhat/Comptroller/Diamond/assetListTest.ts b/tests/hardhat/Comptroller/Diamond/assetListTest.ts index d00d27102..d77e6c841 100644 --- a/tests/hardhat/Comptroller/Diamond/assetListTest.ts +++ b/tests/hardhat/Comptroller/Diamond/assetListTest.ts @@ -22,6 +22,18 @@ chai.use(smock.matchers); const { Error } = ComptrollerErrorReporter; +const actions = { + MINT: 0, + REDEEM: 1, + BORROW: 2, + REPAY: 3, + SEIZE: 4, + LIQUIDATE: 5, + TRANSFER: 6, + ENTER_MARKET: 7, + EXIT_MARKET: 8, +}; + describe("Comptroller: assetListTest", () => { let root: Signer; // eslint-disable-line @typescript-eslint/no-unused-vars let customer: Signer; @@ -123,6 +135,28 @@ describe("Comptroller: assetListTest", () => { return receipt; } + async function unlistAndCheckMarket( + unlistToken: FakeContract, + expectedTokens: FakeContract[], + membershipTokens: FakeContract[] = [], + expectedError: ComptrollerErrorReporter.Error | null = null, + ) { + const reply = await comptroller.connect(customer).callStatic.unlistMarket(unlistToken.address); + + const receipt = await comptroller.connect(customer).unlistMarket(unlistToken.address); + expect(receipt).to.emit(unitroller, "MarketUnlisted"); + + const expectedError_ = expectedError || Error.NO_ERROR; + expect(reply).to.equal(expectedError_); + + const assetsIn = await comptroller.getAssetsIn(await customer.getAddress()); + expect(assetsIn).to.deep.equal(expectedTokens.map(t => t.address)); + + await checkMarkets(membershipTokens); + + return receipt; + } + async function enterAndExpectRejection(enterTokens: FakeContract[], expectedReason: string = "") { await expect(comptroller.connect(customer).enterMarkets(enterTokens.map(t => t.address))).to.be.revertedWith( expectedReason, @@ -232,6 +266,7 @@ describe("Comptroller: assetListTest", () => { describe("entering from borrowAllowed", () => { beforeEach(async () => { await BAT.borrowIndex.returns(convertToUnit(1, 18)); + await comptroller._setMarketBorrowCaps([BAT.address], [convertToUnit(100, 18)]); }); it("enters when called by a vtoken", async () => { @@ -266,4 +301,38 @@ describe("Comptroller: assetListTest", () => { expect(assetsIn).to.deep.equal([BAT.address]); }); }); + + describe("unlistMarkets", () => { + it("properly emits events and unlist market", async () => { + await enterAndCheckMarkets([OMG, BAT, ZRX], [OMG, BAT, ZRX]); + + await comptroller + .connect(customer) + ._setActionsPaused( + [OMG.address], + [ + actions.MINT, + actions.REDEEM, + actions.BORROW, + actions.REPAY, + actions.SEIZE, + actions.ENTER_MARKET, + actions.LIQUIDATE, + actions.TRANSFER, + actions.SEIZE, + actions.EXIT_MARKET, + ], + true, + ); + + await unlistAndCheckMarket(OMG, [BAT, ZRX], [OMG, BAT, ZRX]); + }); + + it("reverts when unlisting not a listed market", async () => { + const vToken = await smock.fake("contracts/Tokens/VTokens/VBep20Immutable.sol:VBep20Immutable"); + await enterAndCheckMarkets([BAT, ZRX], [BAT, ZRX]); + + await unlistAndCheckMarket(vToken, [BAT, ZRX], [BAT, ZRX], Error.MARKET_NOT_LISTED); + }); + }); }); diff --git a/tests/hardhat/Comptroller/Diamond/comptrollerTest.ts b/tests/hardhat/Comptroller/Diamond/comptrollerTest.ts index 442505647..a5228d7fc 100644 --- a/tests/hardhat/Comptroller/Diamond/comptrollerTest.ts +++ b/tests/hardhat/Comptroller/Diamond/comptrollerTest.ts @@ -873,5 +873,65 @@ describe("Comptroller", () => { }); }); }); + + describe("borrow", () => { + let comptrollerLens: FakeContract; + + beforeEach(async () => { + const contracts = await loadFixture(deploy); + comptrollerLens = contracts.comptrollerLens; + // ({ comptroller, oracle, vToken } = await loadFixture(deploy)); + configureVToken(contracts.vToken, contracts.unitroller); + configureOracle(contracts.oracle); + }); + + it("allows borrowing if cap is not reached", async () => { + const cap = convertToUnit("1001", 18); + const currentVTokenBorrows = convertToUnit("500", 18); + + vToken.totalBorrows.returns(currentVTokenBorrows); + vToken.borrowIndex.returns(1); + comptrollerLens.getHypotheticalAccountLiquidity.returns([0, 0, 0]); + await comptroller._setMarketBorrowCaps([vToken.address], [cap]); + + expect( + await comptroller + .connect(vToken.wallet) + .callStatic.borrowAllowed(vToken.address, root.address, convertToUnit("0.9999", 18)), + ).to.equal(0); // 0 means "no error" + }); + + it("reverts borrowing if borrow cap is reached", async () => { + const cap = convertToUnit("100", 18); + const currentVTokenBorrows = convertToUnit("500", 18); + + vToken.totalBorrows.returns(currentVTokenBorrows); + vToken.borrowIndex.returns(1); + comptrollerLens.getHypotheticalAccountLiquidity.returns([0, 0, 0]); + await comptroller._setMarketBorrowCaps([vToken.address], [cap]); + + await expect( + comptroller + .connect(vToken.wallet) + .callStatic.borrowAllowed(vToken.address, root.address, convertToUnit("0.9999", 18)), + ).to.be.revertedWith("market borrow cap reached"); + }); + + it("reverts borrowing if borrow cap is 0", async () => { + const cap = convertToUnit("0", 18); + const currentVTokenBorrows = convertToUnit("500", 18); + + vToken.totalBorrows.returns(currentVTokenBorrows); + vToken.borrowIndex.returns(1); + comptrollerLens.getHypotheticalAccountLiquidity.returns([0, 0, 0]); + await comptroller._setMarketBorrowCaps([vToken.address], [cap]); + + await expect( + comptroller + .connect(vToken.wallet) + .callStatic.borrowAllowed(vToken.address, root.address, convertToUnit("0.9999", 18)), + ).to.be.revertedWith("market borrow cap is 0"); + }); + }); }); }); diff --git a/tests/hardhat/EvilXToken.ts b/tests/hardhat/EvilXToken.ts index cb60a99bb..68ee4b51f 100644 --- a/tests/hardhat/EvilXToken.ts +++ b/tests/hardhat/EvilXToken.ts @@ -167,6 +167,11 @@ describe("Evil Token test", async () => { [convertToUnit(1, 18), convertToUnit(1, 18), convertToUnit(1, 18)], ); + await unitroller._setMarketBorrowCaps( + [vToken1.address, vToken2.address, vToken3.address], + [convertToUnit(1, 18), convertToUnit(1, 18), convertToUnit(1, 18)], + ); + await unitroller.connect(user).enterMarkets([vToken1.address, vToken2.address, vToken3.address]); await underlying1.harnessSetBalance(user.address, convertToUnit(1, 8)); await underlying1.connect(user).approve(vToken1.address, convertToUnit(1, 10)); diff --git a/tests/hardhat/Fork/TokenRedeemer.ts b/tests/hardhat/Fork/TokenRedeemer.ts index 37a5a2777..642cb189e 100644 --- a/tests/hardhat/Fork/TokenRedeemer.ts +++ b/tests/hardhat/Fork/TokenRedeemer.ts @@ -112,6 +112,10 @@ const setupLocal = async (): Promise => { [vToken.address, vToken2.address, vBNB.address], [ethers.constants.MaxUint256, ethers.constants.MaxUint256, ethers.constants.MaxUint256], ); + await comptroller._setMarketBorrowCaps( + [vToken.address, vToken2.address, vBNB.address], + [ethers.constants.MaxUint256, ethers.constants.MaxUint256, ethers.constants.MaxUint256], + ); await comptroller._setCollateralFactor(vToken.address, parseUnits("0.9", 18)); const underlying = await ethers.getContractAt("FaucetToken", await vToken.underlying()); const underlying2 = await ethers.getContractAt("FaucetToken", await vToken2.underlying());